diff --git a/.env.example b/.env.example
index 37c4330..8867ceb 100644
--- a/.env.example
+++ b/.env.example
@@ -20,7 +20,7 @@ MAX_VIEWERS_PER_ROOM=8
# A peer child or Host SFU publication consumes one copy. Valid values: 1, 2, 3.
ENDPOINT_MEDIA_COPY_CAPACITY=2
# During pre-release route canaries, this enables sanitized room/ordinal events.
-# SCREENER_DEBUG=route
+# PIIK_DEBUG=route
# Optional in-process automatic SFU fallback. Set SFU_UDP_PORT=7882 to enable;
# unset or empty keeps it disabled. Local Client modes never create this listener.
@@ -50,11 +50,11 @@ NAT_PREDICTION_ENABLED=false
# Development example (two processes): Vite serves the Browser on 8787 and
# proxies /api, /healthz and /signal to the Go server on 8788. Keep
# PUBLIC_BASE_URL and ALLOWED_ORIGINS on the Browser origin above.
-# SCREENER_ENV=development
+# PIIK_ENV=development
# PORT=8788
# Minimal production example (use independent untracked secrets):
-# SCREENER_ENV=production
+# PIIK_ENV=production
# SITE_ACCESS_PASSWORD=replace-with-an-independent-access-key
# STUN_URLS=stun:stun.example.com:3478
# NAT_PREDICTION_ENABLED=true
diff --git a/.github/workflows/repository-hygiene.yml b/.github/workflows/repository-hygiene.yml
index e9db5ef..9d47e02 100644
--- a/.github/workflows/repository-hygiene.yml
+++ b/.github/workflows/repository-hygiene.yml
@@ -7,7 +7,7 @@ on:
workflow_dispatch:
inputs:
client_checks:
- description: Run the optional Screener Client checks
+ description: Run the optional Piik Client checks
required: false
default: false
type: boolean
@@ -31,7 +31,7 @@ jobs:
- name: Validate tracked project state
run: sh scripts/check-project-state.sh
env:
- SCREENER_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
+ PIIK_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
- name: Install dependencies
run: npm ci
# The Go build embeds internal/server/webassets/dist, so Vite runs first.
@@ -83,7 +83,7 @@ jobs:
- name: Upload application release
uses: actions/upload-artifact@v7
with:
- name: screener-app-${{ github.sha }}
+ name: piik-app-${{ github.sha }}
path: ${{ runner.temp }}/app-release/*
if-no-files-found: error
retention-days: 14
@@ -142,7 +142,7 @@ jobs:
- name: Download application release
uses: actions/download-artifact@v8
with:
- name: screener-app-${{ github.sha }}
+ name: piik-app-${{ github.sha }}
path: ${{ runner.temp }}/app-release
- name: Build and verify Client candidate
run: >-
@@ -153,7 +153,7 @@ jobs:
- name: Upload Client release candidate
uses: actions/upload-artifact@v7
with:
- name: screener-client-${{ matrix.target }}-${{ github.sha }}
+ name: piik-client-${{ matrix.target }}-${{ github.sha }}
path: ${{ runner.temp }}/client-release/*
if-no-files-found: error
compression-level: 0
diff --git a/AGENTS.md b/AGENTS.md
index b23e853..62ff490 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -23,7 +23,7 @@
## Product Contract
-- Screener is private game screen sharing for one Host and up to 20 authenticated
+- Piik is private game screen sharing for one Host and up to 20 authenticated
Viewers, with Web Host/Viewer/relay as the current product surface.
- Current product truth is split by owner:
[rooms/access](./docs/product/rooms-access.md),
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c32205f..4e67ffc 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -55,7 +55,7 @@ Clean up worktrees and branches only after semantic review and integration are c
- Use current community issues and operational reports to identify real compatibility failures, but label anecdotal evidence as such.
- Include a date and direct URLs. Separate verified facts, measurements, assumptions, and recommendations.
- Review licenses before copying implementation code. A useful reference is not automatically a compatible dependency.
-- Screener-owned code is [MIT-licensed](./LICENSE); third-party components retain
+- Piik-owned code is [MIT-licensed](./LICENSE); third-party components retain
their own licenses and notices. GPL/AGPL implementation sources remain
study-only unless a separate distribution decision accepts their obligations.
diff --git a/LICENSE b/LICENSE
index 321ba7b..6e6345a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2026 TNTcraft and Screener contributors
+Copyright (c) 2026 TNTcraft and Piik contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/LICENSE.zh-CN.md b/LICENSE.zh-CN.md
index a3c56bb..3071655 100644
--- a/LICENSE.zh-CN.md
+++ b/LICENSE.zh-CN.md
@@ -4,10 +4,10 @@ The authoritative license is the English [LICENSE](./LICENSE).
This translation is for convenience and adds no terms or restrictions.
本文件为方便阅读提供中文参考译文,不替代英文 [LICENSE](./LICENSE),
-也不增加条件或限制。Screener 自有代码的 MIT 许可不替代
+也不增加条件或限制。Piik 自有代码的 MIT 许可不替代
[第三方组件的许可与声明](./licenses/README.md)。
-版权所有 (c) 2026 TNTcraft 和 Screener 贡献者
+版权所有 (c) 2026 TNTcraft 和 Piik 贡献者
特此免费授予任何获得本软件及相关文档文件(以下简称“软件”)副本的人,
不受限制地处置本软件的权利,包括但不限于使用、复制、修改、合并、出版、
diff --git a/README.md b/README.md
index 1672b0e..3679684 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,18 @@
-
+
-# Screener
+# Piik
English | [简体中文](./README.zh-CN.md)
Share your screen. Bring your friends.
-Screener is private screen sharing for one Host and up to 20 invited friends.
+Piik is private screen sharing for one Host and up to 20 invited friends.
Friends watch in their browsers, with no installation.
```mermaid
flowchart LR
Browser[Browser] --> Host[Host a room]
- Client[Screener Client] --> Host
+ Client[Piik Client] --> Host
Host -->|Invite link| Friends[Friends watch in browsers]
```
@@ -21,12 +21,12 @@ flowchart LR
1. Open the invitation your friend sent.
2. Press Play if your browser asks. Use the video's sound and fullscreen controls.
-Got a room code instead? Open the same Screener site and choose **Join a room**.
+Got a room code instead? Open the same Piik site and choose **Join a room**.
Site access and the room's password settings still apply.
## Share from your browser
-1. Open the Screener site your group uses. Enter its site password if asked.
+1. Open the Piik site your group uses. Enter its site password if asked.
2. Choose **Start sharing**, pick a screen, window or tab, and check the sound switch.
3. Send the room's invitation link to your friends. Keep the sharing tab open.
@@ -39,20 +39,20 @@ same controls, with light and dark themes.
With a Client package for your platform:
1. Extract the whole package, keeping `runtime` beside the executable.
-2. Open `screener-client.exe` on Windows, `Screener Client.app` on macOS, or
- `./screener-client` on Linux.
+2. Open `piik-client.exe` on Windows, `Piik Client.app` on macOS, or
+ `./piik-client` on Linux.
3. Choose a mode, pick what to share, and send the invitation. Keep Client running.
| Mode | Use it for |
| --- | --- |
| **Local room** | Friends on the same local network. An optional site password controls access. |
| **Public invite** | A temporary Internet invitation. The link lasts for this Client run; media remains P2P. |
-| **Connect to Site** | An existing Screener site, with Client capture and media capabilities available in the same browser UI. |
+| **Connect to Site** | An existing Piik site, with Client capture and media capabilities available in the same browser UI. |
Client opens your system browser. Its package includes the Go application and
capture/link helpers; running it needs no Node.js, npm or Go installation.
Linux native capture uses the system Portal, PipeWire and GStreamer stack.
-See the [Client guide](./cmd/screener-client/README.md) for platform details.
+See the [Client guide](./cmd/piik-client/README.md) for platform details.
Temporary public links use Cloudflare Quick Tunnel, which has no uptime guarantee.
Media needs a working UDP path; restrictive networks or browser/OS suspension
@@ -75,9 +75,9 @@ Include your version, OS/browser, expected result and steps to reproduce.
For a local report, start Client with `--debug` and press `D`, or add `?debug=1`
before any `#` in the Browser page URL and use its header download button. Review reports before
sharing; see [diagnostics and export](./docs/reference/configuration.md#diagnostics).
-Connection trouble? Try the [Chromium WebRTC FAQ](./cmd/screener-client/README.md#chromium-webrtc-connections).
+Connection trouble? Try the [Chromium WebRTC FAQ](./cmd/piik-client/README.md#chromium-webrtc-connections).
## License
-Screener-owned code is [MIT licensed](./LICENSE). Third-party components retain
+Piik-owned code is [MIT licensed](./LICENSE). Third-party components retain
their own licenses and notices: [licensing guide](./licenses/README.md).
diff --git a/README.zh-CN.md b/README.zh-CN.md
index d3f7b0b..4e463bd 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,18 +1,18 @@
-
+
-# Screener
+# Piik
[English](./README.md) | 简体中文
分享你的屏幕,叫上朋友一起看。
-Screener 是一个私密屏幕分享工具:一位房主,最多 20 位受邀好友。
+Piik 是一个私密屏幕分享工具:一位房主,最多 20 位受邀好友。
朋友用浏览器就能观看,无须安装。
```mermaid
flowchart LR
Browser[浏览器] --> Host[开房分享]
- Client[Screener Client] --> Host
+ Client[Piik Client] --> Host
Host -->|邀请链接| Friends[好友用浏览器观看]
```
@@ -21,12 +21,12 @@ flowchart LR
1. 打开朋友发来的邀请链接。
2. 如果浏览器提示,点击播放。声音和全屏由视频控件控制。
-只有房间号?打开同一个 Screener 站点,选择 **加入房间**。
+只有房间号?打开同一个 Piik 站点,选择 **加入房间**。
站点访问权限和房间密码设置仍然适用。
## 用浏览器分享
-1. 打开你们使用的 Screener 站点,按提示输入站点密码。
+1. 打开你们使用的 Piik 站点,按提示输入站点密码。
2. 点击 **开始分享**,选择屏幕、窗口或标签页,并检查声音开关。
3. 把房间邀请链接发给朋友,保持分享标签页打开。
@@ -38,19 +38,19 @@ flowchart LR
拿到对应平台的 Client 程序包后:
1. 完整解压,保留可执行文件旁的 `runtime` 目录。
-2. Windows 打开 `screener-client.exe`,macOS 打开 `Screener Client.app`,
- Linux 运行 `./screener-client`。
+2. Windows 打开 `piik-client.exe`,macOS 打开 `Piik Client.app`,
+ Linux 运行 `./piik-client`。
3. 选择模式和分享来源,发出邀请。分享期间保持 Client 运行。
| 模式 | 适合什么情况 |
| --- | --- |
| **本地房间** | 与同一局域网内的好友分享,可设置站点访问密码。 |
| **公网邀请** | 生成本次 Client 运行期间有效的临时邀请链接;媒体仍走 P2P。 |
-| **连接站点** | 使用已有 Screener 站点,并在同一浏览器界面使用 Client 的采集与媒体能力。 |
+| **连接站点** | 使用已有 Piik 站点,并在同一浏览器界面使用 Client 的采集与媒体能力。 |
Client 会打开系统浏览器。程序包包含 Go 应用和采集、临时链接辅助程序,
运行时无须安装 Node.js、npm 或 Go。Linux 原生采集使用系统的 Portal、PipeWire
-和 GStreamer,平台细节见 [Client 指南](./cmd/screener-client/README.md)。
+和 GStreamer,平台细节见 [Client 指南](./cmd/piik-client/README.md)。
临时公网链接使用 Cloudflare Quick Tunnel,不保证持续可用。
媒体需要可用的 UDP 路径;网络限制、浏览器或系统挂起都可能中断分享。
@@ -71,9 +71,9 @@ SFU 后备路径。搭建自己的站点,请看 [自托管指南](./docs/opera
Client 可用 `--debug` 启动后按 `D` 导出本地报告;浏览器网址加上 `?debug=1`
后(放在 `#` 之前),可点击顶部下载按钮。分享前请检查报告内容,详见
[诊断与导出](./docs/reference/configuration.md#diagnostics)。
-连接不上时,也可以查看 [Chromium WebRTC 常见问题](./cmd/screener-client/README.md#chromium-webrtc-connections)。
+连接不上时,也可以查看 [Chromium WebRTC 常见问题](./cmd/piik-client/README.md#chromium-webrtc-connections)。
## 许可
-Screener 自有代码采用 [MIT 许可](./LICENSE),提供 [中文参考译文](./LICENSE.zh-CN.md)。
+Piik 自有代码采用 [MIT 许可](./LICENSE),提供 [中文参考译文](./LICENSE.zh-CN.md)。
第三方组件保留各自的许可与声明,详见 [许可说明](./licenses/README.md)。
diff --git a/cmd/screener-client/README.md b/cmd/piik-client/README.md
similarity index 87%
rename from cmd/screener-client/README.md
rename to cmd/piik-client/README.md
index d6dc77f..c2adab7 100644
--- a/cmd/screener-client/README.md
+++ b/cmd/piik-client/README.md
@@ -1,14 +1,14 @@
-# Screener Client
+# Piik Client
-Screener Client is the self-contained and native-capability runtime for the same
-Browser application used by Hosted Screener. It does not implement another UI,
+Piik Client is the self-contained and native-capability runtime for the same
+Browser application used by Hosted Piik. It does not implement another UI,
room store, signaling protocol, or route controller.
## Run A Package
Extract the matching platform bundle in full and keep `runtime` beside the
-Client executable. Run `screener-client.exe` on Windows, `./screener-client` on
-Linux, or `Screener Client.app` on macOS. The launcher opens in the system Browser;
+Client executable. Run `piik-client.exe` on Windows, `./piik-client` on
+Linux, or `Piik Client.app` on macOS. The launcher opens in the system Browser;
the Client does not embed a browser UI. Packaged execution needs no Node.js, npm,
or Go installation. Linux native capture uses the system dependencies described
in the [Linux capture guide](../../native/capture/linux/README.md).
@@ -111,7 +111,7 @@ to one Browser brand or to VPN use.
Check the Browser's WebRTC/IP-handling policy and any extension's WebRTC or
IP-leak protection setting. Restore a policy that permits WebRTC UDP, reload
-Screener, and verify that another extension or managed policy has not overridden
+Piik, and verify that another extension or managed policy has not overridden
the choice. Setting names and availability differ between Browsers. For example,
Vivaldi exposes **Settings > Privacy and Security > WebRTC IP Handling >
Broadcast IP for Best WebRTC Performance**. Changing this policy can expose
@@ -139,7 +139,7 @@ The binary embeds the Browser assets, so build them before running it:
npm run build:client
go test ./...
go vet ./...
-go run ./cmd/screener-client
+go run ./cmd/piik-client
```
The repository-level entry used locally and by CI is:
@@ -200,11 +200,11 @@ explicit CI packaging, Release publication and updates are documented in
The extracted bundle contains:
```text
-screener-client[.exe]
+piik-client[.exe]
REVISION
LICENSE
THIRD-PARTY-NOTICES.txt
-runtime/native/screener-client-capture[.exe] # supported native-media packages
+runtime/native/piik-client-capture[.exe] # supported native-media packages
runtime/tunnel/cloudflared[.exe] # packages that support --link
```
@@ -212,11 +212,11 @@ The executable embeds the Browser assets of the consumed application release and
carries that same full Git revision as the package `REVISION`. No compatibility
reader accepts a mismatched private build.
-The Windows Client embeds the shared Screener mark through the
-`cmd/screener-client/screener_windows_amd64.syso` resource; the platform
+The Windows Client embeds the shared Piik mark through the
+`cmd/piik-client/piik_windows_amd64.syso` resource; the platform
suffix keeps that Windows resource out of Linux and macOS builds.
Linux packages include the standard `share/applications` desktop entry and
-hicolor icon. macOS packages include a thin `Screener Client.app` launcher
+hicolor icon. macOS packages include a thin `Piik Client.app` launcher
with an ICNS resource; the raw Go executable remains available beside it.
For a native Host smoke run, launch the Client and select a window in the Host
@@ -235,53 +235,53 @@ and without Chromium Local Network Access permission. Environment syntax below
is POSIX; use equivalent variables on Windows.
```sh
-SCREENER_CLIENT_LOCAL_GATE=true \
+PIIK_CLIENT_LOCAL_GATE=true \
CHROME_PATH=/path/to/chrome \
-SCREENER_CLIENT_EXE=/path/to/screener-client \
-SCREENER_CLIENT_GATE_LAN_ADDRESS=192.168.1.10 \
+PIIK_CLIENT_EXE=/path/to/piik-client \
+PIIK_CLIENT_GATE_LAN_ADDRESS=192.168.1.10 \
npm run gate:client-local
-SCREENER_CLIENT_LOOPBACK_GATE=true \
+PIIK_CLIENT_LOOPBACK_GATE=true \
CHROME_PATH=/path/to/chrome \
-SCREENER_CLIENT_EXE=/path/to/screener-client \
+PIIK_CLIENT_EXE=/path/to/piik-client \
npm run probe:client-loopback
-SCREENER_CLIENT_MEDIA_GATE=true \
+PIIK_CLIENT_MEDIA_GATE=true \
CHROME_PATH=/path/to/chrome \
-SCREENER_CLIENT_GATE_STUN_URLS=stun::3478 \
+PIIK_CLIENT_GATE_STUN_URLS=stun::3478 \
npm run gate:client-media
-SCREENER_CLIENT_NATIVE_HOST_GATE=true \
+PIIK_CLIENT_NATIVE_HOST_GATE=true \
CHROME_PATH=/path/to/chrome \
-SCREENER_GO=/path/to/go \
+PIIK_GO=/path/to/go \
npm run gate:client-native-host
-SCREENER_CLIENT_NATIVE_HOST_GATE=true \
-SCREENER_CLIENT_CROSS_NAT_GATE=true \
+PIIK_CLIENT_NATIVE_HOST_GATE=true \
+PIIK_CLIENT_CROSS_NAT_GATE=true \
CHROME_PATH=/path/to/chrome \
-SCREENER_GO=/path/to/go \
-SCREENER_REMOTE_HOST= \
-SCREENER_REMOTE_USER= \
-SCREENER_REMOTE_SSH_KEY=/path/to/key \
-SCREENER_CLIENT_GATE_STUN_URLS=stun::3478 \
+PIIK_GO=/path/to/go \
+PIIK_REMOTE_HOST= \
+PIIK_REMOTE_USER= \
+PIIK_REMOTE_SSH_KEY=/path/to/key \
+PIIK_CLIENT_GATE_STUN_URLS=stun::3478 \
npm run gate:client-native-host
-SCREENER_CLIENT_NATIVE_HOST_GATE=true \
-SCREENER_CLIENT_LINK_MEDIA_GATE=true \
+PIIK_CLIENT_NATIVE_HOST_GATE=true \
+PIIK_CLIENT_LINK_MEDIA_GATE=true \
CHROME_PATH=/path/to/chrome \
-SCREENER_GO=/path/to/go \
-SCREENER_CLOUDFLARED=/path/to/cloudflared \
-SCREENER_REMOTE_HOST= \
-SCREENER_REMOTE_USER= \
-SCREENER_REMOTE_SSH_KEY=/path/to/key \
+PIIK_GO=/path/to/go \
+PIIK_CLOUDFLARED=/path/to/cloudflared \
+PIIK_REMOTE_HOST= \
+PIIK_REMOTE_USER= \
+PIIK_REMOTE_SSH_KEY=/path/to/key \
npm run gate:client-native-host
-SCREENER_CLIENT_LINK_GATE=true \
-SCREENER_GO=/path/to/go \
-SCREENER_CLOUDFLARED=/path/to/cloudflared \
-SCREENER_REMOTE_HOST= \
-SCREENER_REMOTE_USER= \
-SCREENER_REMOTE_SSH_KEY=/path/to/key \
+PIIK_CLIENT_LINK_GATE=true \
+PIIK_GO=/path/to/go \
+PIIK_CLOUDFLARED=/path/to/cloudflared \
+PIIK_REMOTE_HOST= \
+PIIK_REMOTE_USER= \
+PIIK_REMOTE_SSH_KEY=/path/to/key \
npm run gate:client-link
```
diff --git a/cmd/screener-client/main.go b/cmd/piik-client/main.go
similarity index 77%
rename from cmd/screener-client/main.go
rename to cmd/piik-client/main.go
index 2d00bec..bee3ae6 100644
--- a/cmd/screener-client/main.go
+++ b/cmd/piik-client/main.go
@@ -1,5 +1,5 @@
-// Command screener-client is the self-contained Screener Client: it opens a
-// configured Screener Site, or runs the Local room authority in-process
+// Command piik-client is the self-contained Piik Client: it opens a
+// configured Piik Site, or runs the Local room authority in-process
// (--local / --link) together with the loopback capability service and the
// native media edge. Flags select the mode; clientapp owns every mode's
// lifecycle.
@@ -13,12 +13,12 @@ import (
"os/signal"
"syscall"
- "github.com/TNTcraftHIM/Screener/internal/client/clientapp"
+ "github.com/TNTcraftHIM/Piik/internal/client/clientapp"
)
func main() {
var options clientapp.Options
- flag.Func("site", "save and open a Screener Site origin", func(value string) error {
+ flag.Func("site", "save and open a Piik Site origin", func(value string) error {
options.Site = value
options.SiteSet = true
return nil
@@ -26,14 +26,14 @@ func main() {
flag.BoolVar(&options.Local, "local", false, "use the self-contained Local room authority")
flag.BoolVar(&options.Link, "link", false, "create one public Viewer invitation link")
flag.BoolVar(&options.Debug, "debug", false, "save opt-in Client diagnostics to rotated files")
- flag.StringVar(&options.LogDir, "log-dir", "", "diagnostic directory (overrides SCREENER_LOG_DIR)")
+ flag.StringVar(&options.LogDir, "log-dir", "", "diagnostic directory (overrides PIIK_LOG_DIR)")
flag.StringVar(&options.CaptureProcess, "capture-process", "", "path to the platform native capture process")
flag.StringVar(&options.TunnelProcess, "tunnel-process", "", "path to the packaged public tunnel process")
flag.StringVar(&options.ConfigPath, "config", "", "path to the Client configuration file")
flag.StringVar(&options.LANAddress, "lan-address", "", "LAN IPv4 address used in Local invitations")
- flag.IntVar(&options.Port, "port", clientapp.DefaultLocalPort, "Local Screener server port")
+ flag.IntVar(&options.Port, "port", clientapp.DefaultLocalPort, "Local Piik server port")
flag.Parse()
- options.DisableBrowser = os.Getenv("SCREENER_CLIENT_GATE_NO_BROWSER") == "true"
+ options.DisableBrowser = os.Getenv("PIIK_CLIENT_GATE_NO_BROWSER") == "true"
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
diff --git a/cmd/screener-client/screener.ico b/cmd/piik-client/piik.ico
similarity index 100%
rename from cmd/screener-client/screener.ico
rename to cmd/piik-client/piik.ico
diff --git a/cmd/screener-client/screener_windows_amd64.syso b/cmd/piik-client/piik_windows_amd64.syso
similarity index 100%
rename from cmd/screener-client/screener_windows_amd64.syso
rename to cmd/piik-client/piik_windows_amd64.syso
diff --git a/cmd/screener-peer-gate/main.go b/cmd/piik-peer-gate/main.go
similarity index 99%
rename from cmd/screener-peer-gate/main.go
rename to cmd/piik-peer-gate/main.go
index 5116dd6..50d2065 100644
--- a/cmd/screener-peer-gate/main.go
+++ b/cmd/piik-peer-gate/main.go
@@ -13,7 +13,7 @@ import (
"sync"
"time"
- "github.com/TNTcraftHIM/Screener/internal/server/protocol"
+ "github.com/TNTcraftHIM/Piik/internal/server/protocol"
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
"github.com/pion/interceptor"
diff --git a/cmd/screener-peer-gate/main_test.go b/cmd/piik-peer-gate/main_test.go
similarity index 100%
rename from cmd/screener-peer-gate/main_test.go
rename to cmd/piik-peer-gate/main_test.go
diff --git a/cmd/screener-server/diagnostics_unix.go b/cmd/piik-server/diagnostics_unix.go
similarity index 89%
rename from cmd/screener-server/diagnostics_unix.go
rename to cmd/piik-server/diagnostics_unix.go
index 8548f31..dc05ad0 100644
--- a/cmd/screener-server/diagnostics_unix.go
+++ b/cmd/piik-server/diagnostics_unix.go
@@ -7,7 +7,7 @@ import (
"os/signal"
"syscall"
- "github.com/TNTcraftHIM/Screener/internal/diagnostics"
+ "github.com/TNTcraftHIM/Piik/internal/diagnostics"
)
func watchDiagnosticExport(recorder *diagnostics.Recorder) func() {
diff --git a/cmd/screener-server/diagnostics_windows.go b/cmd/piik-server/diagnostics_windows.go
similarity index 72%
rename from cmd/screener-server/diagnostics_windows.go
rename to cmd/piik-server/diagnostics_windows.go
index c2687f3..e731b90 100644
--- a/cmd/screener-server/diagnostics_windows.go
+++ b/cmd/piik-server/diagnostics_windows.go
@@ -1,6 +1,6 @@
package main
-import "github.com/TNTcraftHIM/Screener/internal/diagnostics"
+import "github.com/TNTcraftHIM/Piik/internal/diagnostics"
// Windows exports at orderly shutdown; it has no SIGUSR1 equivalent.
func watchDiagnosticExport(*diagnostics.Recorder) func() { return func() {} }
diff --git a/cmd/screener-server/main.go b/cmd/piik-server/main.go
similarity index 87%
rename from cmd/screener-server/main.go
rename to cmd/piik-server/main.go
index 395774e..ae18948 100644
--- a/cmd/screener-server/main.go
+++ b/cmd/piik-server/main.go
@@ -1,4 +1,4 @@
-// Command screener-server is the Hosted Screener entry point: it loads the
+// Command piik-server is the Hosted Piik entry point: it loads the
// environment, serves the embedded Browser UI together with the signaling and
// room API, and stops on SIGINT or SIGTERM. It replaces src/server/index.ts.
//
@@ -23,10 +23,10 @@ import (
"syscall"
"time"
- "github.com/TNTcraftHIM/Screener/internal/diagnostics"
- "github.com/TNTcraftHIM/Screener/internal/server/app"
- "github.com/TNTcraftHIM/Screener/internal/server/config"
- "github.com/TNTcraftHIM/Screener/internal/server/webassets"
+ "github.com/TNTcraftHIM/Piik/internal/diagnostics"
+ "github.com/TNTcraftHIM/Piik/internal/server/app"
+ "github.com/TNTcraftHIM/Piik/internal/server/config"
+ "github.com/TNTcraftHIM/Piik/internal/server/webassets"
)
// shutdownTimeout bounds the ordered stop (signaling, listener, room store).
@@ -81,11 +81,11 @@ func fail(err error) {
func serve(debug bool) (returnedErr error) {
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ReplaceAttr: diagnostics.ReplaceAttr}))
var recorder *diagnostics.Recorder
- if debug || serverDebugEnabled(os.Getenv("SCREENER_DEBUG")) {
+ if debug || serverDebugEnabled(os.Getenv("PIIK_DEBUG")) {
var err error
recorder, err = diagnostics.Open(serverLogDirectory(), "server", BuildRevision)
if err != nil {
- return fmt.Errorf("Screener server diagnostics are unavailable: %w", err)
+ return fmt.Errorf("Piik server diagnostics are unavailable: %w", err)
}
logger = slog.New(slog.NewMultiHandler(logger.Handler(), recorder.Logger().Handler()))
previous, previousWriter, previousFlags := slog.Default(), log.Writer(), log.Flags()
@@ -93,18 +93,18 @@ func serve(debug bool) (returnedErr error) {
dependencyLog := diagnostics.Writer("stdlib")
log.SetOutput(dependencyLog)
log.SetFlags(previousFlags)
- fmt.Fprintln(os.Stderr, "Screener diagnostic log:", recorder.LogPath())
+ fmt.Fprintln(os.Stderr, "Piik diagnostic log:", recorder.LogPath())
stopExport := watchDiagnosticExport(recorder)
defer func() {
stopExport()
_ = dependencyLog.Close()
- logger.Info("screener-server", "event", "stopped", "failed", returnedErr != nil, diagnostics.Error(returnedErr))
+ logger.Info("piik-server", "event", "stopped", "failed", returnedErr != nil, diagnostics.Error(returnedErr))
returnedErr = errors.Join(returnedErr, exportServerDiagnostics(recorder), recorder.Close())
slog.SetDefault(previous)
log.SetOutput(previousWriter)
log.SetFlags(previousFlags)
}()
- logger.Info("screener-server", "event", "start", "revision", BuildRevision)
+ logger.Info("piik-server", "event", "start", "revision", BuildRevision)
}
configuration, err := config.Load(environment())
if err != nil {
@@ -133,7 +133,7 @@ func serve(debug bool) (returnedErr error) {
if err != nil {
return err
}
- fmt.Printf("Screener %s is listening on %s:%d; public URL %s\n",
+ fmt.Printf("Piik %s is listening on %s:%d; public URL %s\n",
BuildRevision, configuration.ListenHost, port, config.Origin(configuration.PublicBaseURL))
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
@@ -155,7 +155,7 @@ func serverDebugEnabled(value string) bool {
}
func serverLogDirectory() string {
- if directory := strings.TrimSpace(os.Getenv("SCREENER_LOG_DIR")); directory != "" {
+ if directory := strings.TrimSpace(os.Getenv("PIIK_LOG_DIR")); directory != "" {
return directory
}
if directories := filepath.SplitList(os.Getenv("LOGS_DIRECTORY")); len(directories) > 0 && directories[0] != "" {
@@ -167,10 +167,10 @@ func serverLogDirectory() string {
func exportServerDiagnostics(recorder *diagnostics.Recorder) error {
path, err := recorder.Export()
if err != nil {
- fmt.Fprintln(os.Stderr, "Screener diagnostic export failed:", err)
+ fmt.Fprintln(os.Stderr, "Piik diagnostic export failed:", err)
return err
}
- fmt.Fprintln(os.Stderr, "Screener diagnostic bundle:", path)
+ fmt.Fprintln(os.Stderr, "Piik diagnostic bundle:", path)
return nil
}
diff --git a/cmd/screener-server/main_test.go b/cmd/piik-server/main_test.go
similarity index 68%
rename from cmd/screener-server/main_test.go
rename to cmd/piik-server/main_test.go
index 94f8e58..e2300de 100644
--- a/cmd/screener-server/main_test.go
+++ b/cmd/piik-server/main_test.go
@@ -7,27 +7,27 @@ import (
)
func TestLoadEnvironmentFileFillsOnlyAbsentVariables(t *testing.T) {
- t.Setenv("SCREENER_TEST_PRESET", "from-the-service")
+ t.Setenv("PIIK_TEST_PRESET", "from-the-service")
path := filepath.Join(t.TempDir(), ".env")
content := "# Application\n" +
- "SCREENER_TEST_PRESET=from-the-file\n" +
- "export SCREENER_TEST_EXPORTED=exported\n" +
- " SCREENER_TEST_QUOTED = \"a b#c\" \n" +
- "SCREENER_TEST_SINGLE=' padded '\n" +
- "SCREENER_TEST_EMPTY=\n" +
- "SCREENER_TEST_MARK=has#hash\n" +
+ "PIIK_TEST_PRESET=from-the-file\n" +
+ "export PIIK_TEST_EXPORTED=exported\n" +
+ " PIIK_TEST_QUOTED = \"a b#c\" \n" +
+ "PIIK_TEST_SINGLE=' padded '\n" +
+ "PIIK_TEST_EMPTY=\n" +
+ "PIIK_TEST_MARK=has#hash\n" +
"\n" +
"not an assignment\n" +
- "#SCREENER_TEST_COMMENTED=never\r\n" +
- "SCREENER_TEST_LAST=tail"
+ "#PIIK_TEST_COMMENTED=never\r\n" +
+ "PIIK_TEST_LAST=tail"
if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
t.Fatal(err)
}
// Setenv registers the restore, Unsetenv makes the name absent for the run.
for _, name := range []string{
- "SCREENER_TEST_EXPORTED", "SCREENER_TEST_QUOTED", "SCREENER_TEST_SINGLE",
- "SCREENER_TEST_EMPTY", "SCREENER_TEST_MARK", "SCREENER_TEST_COMMENTED",
- "SCREENER_TEST_LAST",
+ "PIIK_TEST_EXPORTED", "PIIK_TEST_QUOTED", "PIIK_TEST_SINGLE",
+ "PIIK_TEST_EMPTY", "PIIK_TEST_MARK", "PIIK_TEST_COMMENTED",
+ "PIIK_TEST_LAST",
} {
t.Setenv(name, "absent")
os.Unsetenv(name)
@@ -38,19 +38,19 @@ func TestLoadEnvironmentFileFillsOnlyAbsentVariables(t *testing.T) {
}
for name, want := range map[string]string{
// A variable the service already supplies is never replaced.
- "SCREENER_TEST_PRESET": "from-the-service",
- "SCREENER_TEST_EXPORTED": "exported",
- "SCREENER_TEST_QUOTED": "a b#c",
- "SCREENER_TEST_SINGLE": " padded ",
- "SCREENER_TEST_EMPTY": "",
- "SCREENER_TEST_MARK": "has#hash",
- "SCREENER_TEST_LAST": "tail",
+ "PIIK_TEST_PRESET": "from-the-service",
+ "PIIK_TEST_EXPORTED": "exported",
+ "PIIK_TEST_QUOTED": "a b#c",
+ "PIIK_TEST_SINGLE": " padded ",
+ "PIIK_TEST_EMPTY": "",
+ "PIIK_TEST_MARK": "has#hash",
+ "PIIK_TEST_LAST": "tail",
} {
if got, present := os.LookupEnv(name); !present || got != want {
t.Errorf("%s = %q, present %t; want %q", name, got, present, want)
}
}
- if value, present := os.LookupEnv("SCREENER_TEST_COMMENTED"); present {
+ if value, present := os.LookupEnv("PIIK_TEST_COMMENTED"); present {
t.Errorf("commented assignment was applied as %q", value)
}
}
@@ -75,7 +75,7 @@ func TestServerDiagnosticSelection(t *testing.T) {
t.Fatalf("serverDebugEnabled(%q) = %v, want %v", value, got, want)
}
}
- t.Setenv("SCREENER_LOG_DIR", "")
+ t.Setenv("PIIK_LOG_DIR", "")
t.Setenv("LOGS_DIRECTORY", "")
if got := serverLogDirectory(); got != "logs" {
t.Fatalf("default directory = %q", got)
@@ -84,7 +84,7 @@ func TestServerDiagnosticSelection(t *testing.T) {
if got := serverLogDirectory(); got != "service-logs" {
t.Fatalf("systemd directory = %q", got)
}
- t.Setenv("SCREENER_LOG_DIR", "explicit-logs")
+ t.Setenv("PIIK_LOG_DIR", "explicit-logs")
if got := serverLogDirectory(); got != "explicit-logs" {
t.Fatalf("explicit directory = %q", got)
}
diff --git a/cmd/screener-server/release.go b/cmd/piik-server/release.go
similarity index 96%
rename from cmd/screener-server/release.go
rename to cmd/piik-server/release.go
index 9b1aeec..eb4d188 100644
--- a/cmd/screener-server/release.go
+++ b/cmd/piik-server/release.go
@@ -16,7 +16,7 @@ import (
// defaultReleaseAPIURL is DEFAULT_RELEASE_API_URL: the same published release
// contract the Browser update notice uses (src/client/lib/release-update.ts).
-const defaultReleaseAPIURL = "https://api.github.com/repos/TNTcraftHIM/Screener/releases/latest"
+const defaultReleaseAPIURL = "https://api.github.com/repos/TNTcraftHIM/Piik/releases/latest"
// Exit codes are UPDATE_EXIT_CODES. deploy/check-release.sh forwards them, so a
// checker failure stays distinguishable from "an update exists".
@@ -31,13 +31,13 @@ const (
// releaseUsage is the usage string parseArguments threw, with this binary's
// name in place of the script's.
-const releaseUsage = "Usage: screener-server --check-release --current-file [--api-url ]"
+const releaseUsage = "Usage: piik-server --check-release --current-file [--api-url ]"
const (
// releaseTimeout bounds the whole check; an operator runs it interactively.
releaseTimeout = 5 * time.Second
// releasePathPrefix is RELEASE_PATH_PREFIX: the only accepted release page.
- releasePathPrefix = "/TNTcraftHIM/Screener/releases/tag/"
+ releasePathPrefix = "/TNTcraftHIM/Piik/releases/tag/"
releaseHost = "github.com"
releaseAPIHost = "api.github.com"
)
@@ -116,7 +116,7 @@ func checkRelease(ctx context.Context, currentRevision, apiURL, token string) re
}
request.Header.Set("Accept", "application/vnd.github+json")
request.Header.Set("X-GitHub-Api-Version", "2022-11-28")
- request.Header.Set("User-Agent", "Screener-release-check")
+ request.Header.Set("User-Agent", "Piik-release-check")
if authorizesGitHub(endpoint, token) {
request.Header.Set("Authorization", "Bearer "+strings.TrimSpace(token))
}
@@ -203,7 +203,7 @@ type releaseMetadata struct {
// parseReleaseMetadata ports parseReleaseMetadata. It accepts one shape only: a
// published, non-draft release whose tag is a full commit revision and whose
-// page is exactly https://github.com/TNTcraftHIM/Screener/releases/tag/ with no credentials, port, query or fragment. The returned URL is
// rebuilt from the validated parts so nothing unverified reaches the operator.
func parseReleaseMetadata(payload []byte) (revision string, releaseURL string, ok bool) {
diff --git a/cmd/screener-server/release_test.go b/cmd/piik-server/release_test.go
similarity index 94%
rename from cmd/screener-server/release_test.go
rename to cmd/piik-server/release_test.go
index 9725425..53f9e52 100644
--- a/cmd/screener-server/release_test.go
+++ b/cmd/piik-server/release_test.go
@@ -16,7 +16,7 @@ import (
const (
deployedRevision = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
latestRevision = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
- latestReleaseURL = "https://github.com/TNTcraftHIM/Screener/releases/tag/" + latestRevision
+ latestReleaseURL = "https://github.com/TNTcraftHIM/Piik/releases/tag/" + latestRevision
latestRelease = `{"tag_name":"` + latestRevision + `","html_url":"` + latestReleaseURL + `"}`
)
@@ -40,29 +40,29 @@ func TestParseReleaseMetadataAcceptsOnlyTheStrictReleaseIdentity(t *testing.T) {
{"other host", tagged("https://evil.example"), "", ""},
{
"userinfo",
- tagged("https://user@github.com/TNTcraftHIM/Screener/releases/tag/" + latestRevision),
+ tagged("https://user@github.com/TNTcraftHIM/Piik/releases/tag/" + latestRevision),
"", "",
},
{
"port",
- tagged("https://github.com:8443/TNTcraftHIM/Screener/releases/tag/" + latestRevision),
+ tagged("https://github.com:8443/TNTcraftHIM/Piik/releases/tag/" + latestRevision),
"", "",
},
{
"plaintext page",
- tagged("http://github.com/TNTcraftHIM/Screener/releases/tag/" + latestRevision),
+ tagged("http://github.com/TNTcraftHIM/Piik/releases/tag/" + latestRevision),
"", "",
},
{"query", tagged(latestReleaseURL + "?asset=1"), "", ""},
{"fragment", tagged(latestReleaseURL + "#assets"), "", ""},
{
"encoded path separator",
- tagged("https://github.com/TNTcraftHIM%2FScreener/releases/tag/" + latestRevision),
+ tagged("https://github.com/TNTcraftHIM%2FPiik/releases/tag/" + latestRevision),
"", "",
},
{
"page tag disagrees with the release tag",
- tagged("https://github.com/TNTcraftHIM/Screener/releases/tag/" + deployedRevision),
+ tagged("https://github.com/TNTcraftHIM/Piik/releases/tag/" + deployedRevision),
"", "",
},
{
@@ -144,7 +144,7 @@ func TestCheckReleaseReportsTheDeployedComparison(t *testing.T) {
if got := request.Header.Get("X-GitHub-Api-Version"); got != "2022-11-28" {
t.Errorf("X-GitHub-Api-Version = %q", got)
}
- if got := request.Header.Get("User-Agent"); got != "Screener-release-check" {
+ if got := request.Header.Get("User-Agent"); got != "Piik-release-check" {
t.Errorf("User-Agent = %q", got)
}
writer.WriteHeader(testCase.status)
diff --git a/deploy/check-release.sh b/deploy/check-release.sh
index 7a82b94..a800fd0 100644
--- a/deploy/check-release.sh
+++ b/deploy/check-release.sh
@@ -6,6 +6,6 @@ if [ "$#" -gt 1 ]; then
exit 2
fi
-current_file="${1:-/opt/screener/current/REVISION}"
+current_file="${1:-/opt/piik/current/REVISION}"
-exec /opt/screener/current/screener-server --check-release --current-file "$current_file"
+exec /opt/piik/current/piik-server --check-release --current-file "$current_file"
diff --git a/deploy/container/Dockerfile b/deploy/container/Dockerfile
index b1889b3..e2c87b0 100644
--- a/deploy/container/Dockerfile
+++ b/deploy/container/Dockerfile
@@ -1,8 +1,8 @@
FROM gcr.io/distroless/static-debian13:nonroot-amd64@sha256:e754765ad9e167b0677b41c617fd44afb7b9818a477f48f17bda08e12cfb98cb
WORKDIR /app
-COPY --chmod=0555 screener-server /app/
+COPY --chmod=0555 piik-server /app/
COPY --chmod=0444 LICENSE THIRD-PARTY-NOTICES.txt REVISION /app/
-ENV LISTEN_HOST=0.0.0.0 SCREENER_LOG_DIR=/home/nonroot/logs ROOM_DATABASE_PATH=/home/nonroot/rooms.sqlite
+ENV LISTEN_HOST=0.0.0.0 PIIK_LOG_DIR=/home/nonroot/logs ROOM_DATABASE_PATH=/home/nonroot/rooms.sqlite
USER 65532:65532
EXPOSE 8787/tcp 3478/udp 3479/udp 3480/udp 7882/udp
-ENTRYPOINT ["/app/screener-server"]
+ENTRYPOINT ["/app/piik-server"]
diff --git a/deploy/nginx/share.bonfire.icu.conf.example b/deploy/nginx/share.bonfire.icu.conf.example
index c5906b9..c920c93 100644
--- a/deploy/nginx/share.bonfire.icu.conf.example
+++ b/deploy/nginx/share.bonfire.icu.conf.example
@@ -1,9 +1,9 @@
-map $http_upgrade $screener_connection_upgrade {
+map $http_upgrade $piik_connection_upgrade {
default upgrade;
'' close;
}
-limit_req_zone $binary_remote_addr zone=screener_site_access:10m rate=5r/m;
+limit_req_zone $binary_remote_addr zone=piik_site_access:10m rate=5r/m;
server {
listen 80;
@@ -30,8 +30,8 @@ server {
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
- access_log /var/log/nginx/screener.access.log;
- error_log /var/log/nginx/screener.error.log warn;
+ access_log /var/log/nginx/piik.access.log;
+ error_log /var/log/nginx/piik.error.log warn;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
@@ -48,7 +48,7 @@ server {
}
location = /api/site-access {
- limit_req zone=screener_site_access burst=5 nodelay;
+ limit_req zone=piik_site_access burst=5 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:8787;
proxy_http_version 1.1;
@@ -65,7 +65,7 @@ server {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $screener_connection_upgrade;
+ proxy_set_header Connection $piik_connection_upgrade;
proxy_read_timeout 5h;
proxy_send_timeout 5h;
proxy_buffering off;
diff --git a/deploy/release-app.sh b/deploy/release-app.sh
index 37e8906..9b4434a 100644
--- a/deploy/release-app.sh
+++ b/deploy/release-app.sh
@@ -3,15 +3,15 @@ set -Eeuo pipefail
umask 022
if [ "$#" -ne 1 ]; then
- printf 'usage: SCREENER_PUBLIC_ORIGIN=https://share.example.com %s /opt/screener/uploads/.release.json\n' "$0" >&2
+ printf 'usage: PIIK_PUBLIC_ORIGIN=https://share.example.com %s /opt/piik/uploads/.release.json\n' "$0" >&2
exit 2
fi
-upload_root='/opt/screener/uploads'
-release_root='/opt/screener/releases'
-current='/opt/screener/current'
-lock='/opt/screener/deploy.lock'
-public_origin="${SCREENER_PUBLIC_ORIGIN:-}"
+upload_root='/opt/piik/uploads'
+release_root='/opt/piik/releases'
+current='/opt/piik/current'
+lock='/opt/piik/deploy.lock'
+public_origin="${PIIK_PUBLIC_ORIGIN:-}"
descriptor="$(realpath -e -- "$1")"
stage=''
release_owned=0
@@ -39,8 +39,8 @@ main_asset="$(descriptor_text mainAsset)"
[[ "$revision" =~ ^[0-9a-f]{40}$ ]]
[[ "$release_id" =~ ^[0-9a-f]{7}$ ]]
test "$release_id" = "${revision:0:7}"
-test "$artifact_name" = "screener-${release_id}-runtime.tar.gz"
-test "$manifest_name" = "screener-${release_id}.manifest.tsv"
+test "$artifact_name" = "piik-${release_id}-runtime.tar.gz"
+test "$manifest_name" = "piik-${release_id}.manifest.tsv"
[[ "$artifact_sha" =~ ^[0-9a-f]{64}$ ]]
[[ "$manifest_sha" =~ ^[0-9a-f]{64}$ ]]
[[ "$file_count" =~ ^[1-9][0-9]*$ ]]
@@ -105,7 +105,7 @@ recover() {
trap - ERR HUP INT TERM EXIT
set +e
if [ "$cutover_started" -eq 1 ]; then
- systemctl stop screener.service || ok=0
+ systemctl stop piik.service || ok=0
if [ "$(readlink -f -- "$current" 2>/dev/null)" != "$old_release" ]; then
link="${current}.recover-${release_id}-$$"
if [ -e "$link" ] || [ -L "$link" ]; then
@@ -115,7 +115,7 @@ recover() {
fi
fi
test "$(readlink -f -- "$current" 2>/dev/null)" = "$old_release" || ok=0
- systemctl start screener.service || ok=0
+ systemctl start piik.service || ok=0
wait_for_health || ok=0
fi
rm -f -- "${current}.${release_id}-$$" "${current}.recover-${release_id}-$$" || ok=0
@@ -126,7 +126,7 @@ recover() {
printf 'deployment_failed=%s recovery_ok=%s current=%s active=%s\n' \
"$code" "$ok" \
"$(readlink -f -- "$current" 2>/dev/null || true)" \
- "$(systemctl show screener.service -p ActiveState --value 2>/dev/null || true)" >&2
+ "$(systemctl show piik.service -p ActiveState --value 2>/dev/null || true)" >&2
if [ "$ok" -ne 1 ]; then
exit 90
fi
@@ -150,15 +150,15 @@ test -f "$artifact"
test -f "$manifest"
test "$(sha256sum "$artifact" | awk '{print $1}')" = "$artifact_sha"
test "$(sha256sum "$manifest" | awk '{print $1}')" = "$manifest_sha"
-for service in screener nginx; do
+for service in piik nginx; do
test "$(systemctl show "${service}.service" -p ActiveState --value)" = 'active'
test "$(systemctl show "${service}.service" -p NRestarts --value)" = '0'
done
# The first Go/embedded-media cutover owns its infrastructure recovery separately.
-test -x "$old_release/screener-server"
-old_pid="$(systemctl show screener.service -p MainPID --value)"
+test -x "$old_release/piik-server"
+old_pid="$(systemctl show piik.service -p MainPID --value)"
test "$old_pid" -gt 1
-test "$(readlink -f "/proc/${old_pid}/exe")" = "$old_release/screener-server"
+test "$(readlink -f "/proc/${old_pid}/exe")" = "$old_release/piik-server"
while IFS= read -r raw_entry; do
entry="$raw_entry"
@@ -170,7 +170,7 @@ while IFS= read -r raw_entry; do
esac
case "$entry" in
/*|*\\*) printf 'invalid archive entry: %s\n' "$raw_entry" >&2; exit 41 ;;
- LICENSE|REVISION|THIRD-PARTY-NOTICES.txt|screener-server) ;;
+ LICENSE|REVISION|THIRD-PARTY-NOTICES.txt|piik-server) ;;
*) printf 'unexpected archive entry: %s\n' "$raw_entry" >&2; exit 42 ;;
esac
done < <(tar -tzf "$artifact")
@@ -183,7 +183,7 @@ tar --no-same-owner --no-same-permissions -xzf "$artifact" -C "$stage"
tab=$'\t'
if [ -n "$(tail -c 1 "$manifest")" ]; then exit 61; fi
if grep -qEv "^[0-9a-f]{64}${tab}[0-9]+${tab}[^${tab}]*$" "$manifest"; then exit 62; fi
-if grep -qEv "^[0-9a-f]{64}${tab}[0-9]+${tab}(LICENSE|REVISION|THIRD-PARTY-NOTICES\.txt|screener-server)$" "$manifest"; then exit 63; fi
+if grep -qEv "^[0-9a-f]{64}${tab}[0-9]+${tab}(LICENSE|REVISION|THIRD-PARTY-NOTICES\.txt|piik-server)$" "$manifest"; then exit 63; fi
if [ -n "$(cut -f3 "$manifest" | sort | uniq -d)" ]; then exit 64; fi
if [ "$(wc -l < "$manifest")" -ne "$file_count" ]; then exit 65; fi
if [ -n "$(find "$stage" -type l)" ]; then exit 66; fi
@@ -199,23 +199,23 @@ printf 'artifact_manifest=ok files=%s revision=%s\n' "$file_count" "$revision"
# Set the mode before testing it: an archive packaged on a host without an
# executable bit (Windows) records 0644, and the release owns the bit here.
-chmod 0755 "$stage/screener-server"
-test -x "$stage/screener-server"
+chmod 0755 "$stage/piik-server"
+test -x "$stage/piik-server"
chmod 0644 "$stage/LICENSE" "$stage/REVISION" "$stage/THIRD-PARTY-NOTICES.txt"
# Runs as the service user under the manager (no sudo/polkit round trip) so a
# binary or environment file the service cannot use fails here, before cutover.
systemd-run \
- --uid=screener \
- --gid=screener \
+ --uid=piik \
+ --gid=piik \
--wait \
--collect \
--quiet \
--service-type=exec \
- --property='EnvironmentFile=/etc/screener/screener.env' \
- --property='Environment=SCREENER_ENV=production' \
+ --property='EnvironmentFile=/etc/piik/piik.env' \
+ --property='Environment=PIIK_ENV=production' \
--property='RuntimeMaxSec=20s' \
- "$stage/screener-server" --check-config
+ "$stage/piik-server" --check-config
if [ -n "$(comm -12 <(find "$old_release" -type f -printf '%D:%i\n' | sort -u) <(find "$stage" -type f -printf '%D:%i\n' | sort -u))" ]; then
exit 80
@@ -237,21 +237,21 @@ nginx_restarts="$(systemctl show nginx.service -p NRestarts --value)"
cutover_since="$(date '+%Y-%m-%d %H:%M:%S')"
cutover_start="$(date +%s%3N)"
cutover_started=1
-systemctl stop screener.service
-test "$(systemctl show screener.service -p ActiveState --value)" = 'inactive'
+systemctl stop piik.service
+test "$(systemctl show piik.service -p ActiveState --value)" = 'inactive'
ln -s "$release" "${current}.${release_id}-$$"
mv -Tf "${current}.${release_id}-$$" "$current"
test "$(readlink -f -- "$current")" = "$release"
-systemctl start screener.service
+systemctl start piik.service
wait_for_health
health_ready="$(date +%s%3N)"
-test "$(systemctl show screener.service -p ActiveState --value)" = 'active'
-test "$(systemctl show screener.service -p NRestarts --value)" = '0'
+test "$(systemctl show piik.service -p ActiveState --value)" = 'active'
+test "$(systemctl show piik.service -p NRestarts --value)" = '0'
test "$(systemctl show nginx.service -p NRestarts --value)" = "$nginx_restarts"
test "$(nft list table inet bonfire_filter | sha256sum | awk '{print $1}')" = "$firewall_before"
test "$(readlink -f -- "$current")" = "$release"
-pid="$(systemctl show screener.service -p MainPID --value)"
+pid="$(systemctl show piik.service -p MainPID --value)"
test "$pid" -gt 1
test "$(readlink -f "/proc/${pid}/cwd")" = "$release"
test "$(curl -fsS --max-time 5 http://127.0.0.1:8787/healthz)" = '{"status":"ok"}'
@@ -262,7 +262,7 @@ test "$(curl -sS -o /dev/null -w '%{http_code}' --max-time 8 "$public_origin/$ma
if [ "$old_asset" != "$main_asset" ]; then
test "$(curl -sS -o /dev/null -w '%{http_code}' --max-time 8 "$public_origin/$old_asset")" = '404'
fi
-test -z "$(journalctl -u screener.service --since "$cutover_since" -p warning --no-pager --output=cat)"
+test -z "$(journalctl -u piik.service --since "$cutover_since" -p warning --no-pager --output=cat)"
asset_sha="$(curl -fsS --max-time 8 "$public_origin/$main_asset" | sha256sum | awk '{print $1}')"
release_owned=0
diff --git a/deploy/systemd/screener.service.example b/deploy/systemd/piik.service.example
similarity index 67%
rename from deploy/systemd/screener.service.example
rename to deploy/systemd/piik.service.example
index 4d9af13..7712a8f 100644
--- a/deploy/systemd/screener.service.example
+++ b/deploy/systemd/piik.service.example
@@ -1,24 +1,24 @@
[Unit]
-Description=Screener web, signaling, STUN and SFU application
+Description=Piik web, signaling, STUN and SFU application
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
-User=screener
-Group=screener
-WorkingDirectory=/opt/screener/current
-Environment=SCREENER_ENV=production
-Environment=ROOM_DATABASE_PATH=/var/lib/screener/rooms.sqlite
-EnvironmentFile=/etc/screener/screener.env
-ExecStart=/opt/screener/current/screener-server
+User=piik
+Group=piik
+WorkingDirectory=/opt/piik/current
+Environment=PIIK_ENV=production
+Environment=ROOM_DATABASE_PATH=/var/lib/piik/rooms.sqlite
+EnvironmentFile=/etc/piik/piik.env
+ExecStart=/opt/piik/current/piik-server
Restart=on-failure
RestartSec=3s
TimeoutStopSec=20s
UMask=0077
-StateDirectory=screener
+StateDirectory=piik
StateDirectoryMode=0700
-LogsDirectory=screener
+LogsDirectory=piik
LogsDirectoryMode=0700
NoNewPrivileges=true
diff --git a/docs/README.md b/docs/README.md
index ce453a4..5dbf74e 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,12 +2,12 @@
[English Quick Start](../README.md) · [中文快速开始](../README.zh-CN.md)
-## Use Screener
+## Use Piik
| What you need | Start here |
| --- | --- |
| Join a friend or share a screen | [Quick Start](../README.md) |
-| Run Client, choose a mode, or fix capture trouble | [Client guide](../cmd/screener-client/README.md) |
+| Run Client, choose a mode, or fix capture trouble | [Client guide](../cmd/piik-client/README.md) |
| Collect a useful bug report | [Diagnostics and export](./reference/configuration.md#diagnostics) |
| Host your own site | [Self-hosting](./operations/self-hosting.md) |
| Configure ports, access or persistence | [Configuration reference](./reference/configuration.md) |
@@ -33,7 +33,7 @@ npm run dev
In a second terminal, start the server. For a POSIX shell:
```sh
-PORT=8788 PUBLIC_BASE_URL=http://localhost:8787 go run ./cmd/screener-server
+PORT=8788 PUBLIC_BASE_URL=http://localhost:8787 go run ./cmd/piik-server
```
Or in PowerShell:
@@ -41,8 +41,8 @@ Or in PowerShell:
```powershell
$env:PORT = '8788'
$env:PUBLIC_BASE_URL = 'http://localhost:8787'
-go build -o build/dev/screener-server.exe ./cmd/screener-server
-./build/dev/screener-server.exe
+go build -o build/dev/piik-server.exe ./cmd/piik-server
+./build/dev/piik-server.exe
```
The fixed Windows executable path avoids repeated firewall prompts from `go run`.
@@ -87,7 +87,7 @@ Browse [all ADRs](./adr/) for their context and consequences.
results, failed controls and limits; neither promises universal performance.
- [Research directory](./research/): transport, capture, platform and backend evidence.
- [Maintenance](./maintenance.md): document ownership and repository lifecycle.
-- [Licensing](../licenses/README.md): Screener's MIT scope and third-party notices.
+- [Licensing](../licenses/README.md): Piik's MIT scope and third-party notices.
Research distinguishes observations from assumptions. Product modules own
accepted behavior, source and tests own implementation detail, and Git/PRs own
diff --git a/docs/adr/0001-p2p-first-media-topology.md b/docs/adr/0001-p2p-first-media-topology.md
index de7b5a4..0b8e702 100644
--- a/docs/adr/0001-p2p-first-media-topology.md
+++ b/docs/adr/0001-p2p-first-media-topology.md
@@ -5,7 +5,7 @@
## Durable Rationale
-Screener serves one broadcaster and a small group of trusted friends. Low
+Piik serves one broadcaster and a small group of trusted friends. Low
latency, private access, browser viewing, and low server media cost matter more
than public-broadcast scale. Direct WebRTC therefore remains the preferred
media path, while centralized media is fallback infrastructure rather than the
diff --git a/docs/adr/0002-memory-resident-protected-rooms.md b/docs/adr/0002-memory-resident-protected-rooms.md
index 349e2ee..a85fffd 100644
--- a/docs/adr/0002-memory-resident-protected-rooms.md
+++ b/docs/adr/0002-memory-resident-protected-rooms.md
@@ -5,7 +5,7 @@
## Context
-Screener serves one Host and at most 20 trusted Viewers. The application server
+Piik serves one Host and at most 20 trusted Viewers. The application server
owns a small room and authorization aggregate while WebRTC and LiveKit own live
media sessions. Frequent application releases should not force the Host to
create another room or redistribute invitations, but a database must not become
diff --git a/docs/adr/0005-automatic-hybrid-media-routing.md b/docs/adr/0005-automatic-hybrid-media-routing.md
index 59fcd96..408efc6 100644
--- a/docs/adr/0005-automatic-hybrid-media-routing.md
+++ b/docs/adr/0005-automatic-hybrid-media-routing.md
@@ -12,7 +12,7 @@ describe the earlier implementation and its production history.
## Context
-Direct Browser WebRTC gives Screener its desired latency and distributed cost,
+Direct Browser WebRTC gives Piik its desired latency and distributed cost,
but one Host cannot fan out to every Viewer and some endpoint pairs cannot
establish usable direct media. The product needs automatic peer distribution and
bounded server fallback without exposing topology choices to users or turning
@@ -214,7 +214,7 @@ tokens. Replacement, abort, timeout, confirmed media-participant loss, share
rollover, stop, and room deletion transfer the resources they own into the same typed drain path.
Only successful room deletion plus an absence readback releases that generation,
so a stale token cannot recreate off-ledger media. The deployment must dedicate
-the LiveKit namespace to Screener and complete startup ownership/cleanup before
+the LiveKit namespace to Piik and complete startup ownership/cleanup before
accepting traffic; [self-hosting operations](../operations/self-hosting.md) owns
that procedure.
@@ -236,7 +236,7 @@ capacity poll or second resource-specific controller.
Ordinary Peers use deployment STUN only. Browser SFU PeerConnections use an
empty external ICE-server list while retaining LiveKit-signaled UDP candidates.
-Screener configures no TURN, ICE/TCP, media TCP, or TLS-relayed media. A future
+Piik configures no TURN, ICE/TCP, media TCP, or TLS-relayed media. A future
strict-firewall transport must be accepted as a LiveKit-internal capability, not
as another application route candidate.
@@ -270,7 +270,7 @@ they mean only one complete same-identity `qualityLimitationReason` delta in
experiment; it does not locate the physical bottleneck or prove end-to-end
quality. `other`, missing, reset, hidden, or stale evidence is unknown. SFU
publication and subscription state remains owned by LiveKit plus the exact
-Viewer's continuing decoded progress. Screener does not combine loss, RTT,
+Viewer's continuing decoded progress. Piik does not combine loss, RTT,
jitter, bitrate, FPS, resolution, or freezes into a weighted route score.
Routing degradation requires three consecutive complete degraded deltas for the
diff --git a/docs/adr/0007-path-isolated-representation-quality.md b/docs/adr/0007-path-isolated-representation-quality.md
index ffecd29..5f9ec98 100644
--- a/docs/adr/0007-path-isolated-representation-quality.md
+++ b/docs/adr/0007-path-isolated-representation-quality.md
@@ -12,12 +12,12 @@ implementation; [media quality](../product/media-quality.md) owns current behavi
## Context
-Screener sends one realtime game-screen source through independent P2P
+Piik sends one realtime game-screen source through independent P2P
connections and, when needed, one shared LiveKit publication. WebRTC and
LiveKit already own congestion control, encoder adaptation, retransmission,
simulcast construction, subscriber bandwidth estimation, and layer selection.
-Earlier experiments added a Screener-defined lower SFU encoding and treated
+Earlier experiments added a Piik-defined lower SFU encoding and treated
quality preference as an application policy. Production evidence showed that
an always-active lower encoding can compete with the highest encoding on a
constrained Host-to-SFU path. It did not justify replacing LiveKit's native
@@ -123,7 +123,7 @@ than claiming complete source isolation.
## Consequences
-- Screener owns fewer media mechanisms and follows the pinned frameworks'
+- Piik owns fewer media mechanisms and follows the pinned frameworks'
supported control surfaces.
- A capable Browser Host or relay can use H.264 hardware encoding while another
sender remains on VP8 without a room-protocol branch; the Host can explicitly
@@ -136,7 +136,7 @@ than claiming complete source isolation.
outbound video sender but no additional capture or encoder beyond the sender
that already exists.
- A Host may need to lower its explicit share profile when encoder or uplink
- capacity is insufficient; Screener does not silently remove constrained
+ capacity is insufficient; Piik does not silently remove constrained
Viewer support.
- ADR-0005's native-edge local convergence is deployed and performs bounded
real-candidate comparisons without owning media adaptation. Weighted or global
@@ -144,7 +144,7 @@ than claiming complete source isolation.
## Stop Lines
-- No Screener resolution/FPS/bitrate ladder or representation formula.
+- No Piik resolution/FPS/bitrate ladder or representation formula.
- No codec wire/state, GPU/MFT allowlist, persistent codec cache, parallel
VP8/H.264 route, active-edge codec churn, or LiveKit backup publication. The
local pre-share Host selector is the only manual codec surface.
diff --git a/docs/adr/0010-cross-platform-client-runtime.md b/docs/adr/0010-cross-platform-client-runtime.md
index 320bc5c..0af41bb 100644
--- a/docs/adr/0010-cross-platform-client-runtime.md
+++ b/docs/adr/0010-cross-platform-client-runtime.md
@@ -15,12 +15,12 @@
## Context
-The Browser is the current Screener interaction surface, but it cannot own native
+The Browser is the current Piik interaction surface, but it cannot own native
capture, hardware encode, or reusable native sockets. A self-contained package
must add those capabilities without creating another room model, signaling
protocol, route controller, or UI.
-Existing Screener room, admission, signaling, and routing behavior already has
+Existing Piik room, admission, signaling, and routing behavior already has
one TypeScript implementation. Rewriting that behavior in the Helper would make
Hosted and Local deployments diverge without improving the media path.
@@ -37,7 +37,7 @@ topologies and makes a saved Site unavailable while another room source runs.
core and the same built Browser assets with local configuration; no
deployment gets a second product core. Its implementation is owned by
[ADR-0012](./0012-shared-go-backend-core.md).
-2. The packaged product is Screener Client. Its Go process is the cross-platform
+2. The packaged product is Piik Client. Its Go process is the cross-platform
entry and native capability provider. It starts `/health` and one `/control`
endpoint on IPv4 loopback within ports `39721` through `39730` before room-
source selection and retains them until the process exits.
@@ -61,7 +61,7 @@ topologies and makes a saved Site unavailable while another room source runs.
with the page; a picker, share, or room source does not own the socket. The
Browser forwards current signaling and remains the participant.
5. A platform package contains one Go executable carrying the same core and
- embedded Browser assets used by Hosted Screener. It may also carry one
+ embedded Browser assets used by Hosted Piik. It may also carry one
process-isolated capture binary and the pinned `cloudflared` sidecar. Those
sidecars are the only supervised children and keep their bounded lifetime.
Platform packaging is metadata around that entry, not another long-running
@@ -74,7 +74,7 @@ topologies and makes a saved Site unavailable while another room source runs.
network permission. Clearing Site data simply requires opening it from the
Client again.
7. A self-contained Local deployment serves reachable LAN peers without a
- central Screener service. Its explicit `--link` mode starts one accountless
+ central Piik service. Its explicit `--link` mode starts one accountless
Cloudflare Quick Tunnel for the same HTTP/WebSocket surface. The Client
reserves the exact IPv4 listener before creating that tunnel, then applies
its HTTPS origin before the server starts serving that listener. It retains the same
@@ -162,7 +162,7 @@ topologies and makes a saved Site unavailable while another room source runs.
target and must start the assembled Local authority, pass `/healthz`, and
stop it cleanly before the candidate is accepted.
14. The root package manifest is the single dependency contract for the Browser
- bundle and repository tooling. No host installs packages to run Screener, so
+ bundle and repository tooling. No host installs packages to run Piik, so
the manifest has no runtime half, and no second Client dependency list or
post-install package surgery is used.
diff --git a/docs/adr/0012-shared-go-backend-core.md b/docs/adr/0012-shared-go-backend-core.md
index d17c50c..bc64483 100644
--- a/docs/adr/0012-shared-go-backend-core.md
+++ b/docs/adr/0012-shared-go-backend-core.md
@@ -26,7 +26,7 @@ the same Browser build.
## Decision
1. One Go module at the repository root owns the product core.
- `cmd/screener-server` (Hosted) and `cmd/screener-client` (Client) are entry
+ `cmd/piik-server` (Hosted) and `cmd/piik-client` (Client) are entry
points over the same `internal/server` packages and own only their defaults,
reachability, and lifecycle policy. Neither reimplements rooms, admission,
signaling, or routing. The TypeScript server, its bundled runtime, the process
@@ -65,7 +65,7 @@ the same Browser build.
[ADR-0002](./0002-memory-resident-protected-rooms.md). Both storage modes,
their validation, and their failure policy are unchanged, and no build
requires a C toolchain.
-8. The port changes no contract. Signaling stays `screener-v21`, the Client
+8. The port changed no contract. Signaling stayed on its then-current v21 wire; the Client
loopback stays v8, capture framing stays v4, and the HTTP API, cookies, error
codes, and close codes keep their exact shapes. No compatibility alias, dual
reader, or migration is added for a change of implementation language.
diff --git a/docs/adr/0013-embedded-node-local-media.md b/docs/adr/0013-embedded-node-local-media.md
index 98f332d..a7845cb 100644
--- a/docs/adr/0013-embedded-node-local-media.md
+++ b/docs/adr/0013-embedded-node-local-media.md
@@ -5,7 +5,7 @@
## Context
-The owner accepts one self-contained Screener process for the current STUN and
+The owner accepts one self-contained Piik process for the current STUN and
SFU services, and one shared encoded-media model for capable Native P2P nodes
and the SFU. Bundling or supervising coturn/LiveKit executables does not meet
this requirement. The existing product uses coturn only as STUN, not TURN.
@@ -28,7 +28,7 @@ acceptance. Mature simulcast implementations provide the starting model.
produce the highest required output and its lower fallbacks, and stop upper
outputs no child needs. This is not a promise of a single Host encode under
all conditions. Representation settings come from the chosen media component
- within Host ceilings, not a new Screener quality score or arbitrary ladder.
+ within Host ceilings, not a new Piik quality score or arbitrary ladder.
4. Each child receives only its selected output. Multiple active encodings do
not imply sending every output to every child. Preserve the original input,
source clock and unaffected siblings. Playback quality, cadence and recovery
diff --git a/docs/adr/0014-browser-node-local-encoding-pool.md b/docs/adr/0014-browser-node-local-encoding-pool.md
index 4b7b904..c5fb0bf 100644
--- a/docs/adr/0014-browser-node-local-encoding-pool.md
+++ b/docs/adr/0014-browser-node-local-encoding-pool.md
@@ -29,7 +29,7 @@ in [ADR-0011](./0011-browser-assisted-native-fanout.md) remains independently ow
upstream subscription, room-wide minimum or topology operation is introduced.
2. Each group uses stock WebRTC encoding and adaptation through an independent
local producer. Each outgoing connection retains stock ICE, DTLS-SRTP,
- bandwidth estimation, RTP packetization, pacing and loss recovery. Screener
+ bandwidth estimation, RTP packetization, pacing and loss recovery. Piik
connects existing demand observations to group budgets and membership; it
adds no congestion estimator, quality score or arbitrary resolution ladder.
3. Reuse `HostPeer` and its existing signaling, sender-mutation and retirement
diff --git a/docs/deployment.md b/docs/deployment.md
index aa2d40c..1c8ecf1 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -15,7 +15,7 @@ bootstrap/updater; do not call this wrapper generic.
## Release Boundary
-A routine application release changes only the built Screener server binary and
+A routine application release changes only the built Piik server binary and
the Browser assets it embeds. It does not change infrastructure,
service units, proxy/firewall rules, secrets, media listener configuration, or
persistent room state.
@@ -42,16 +42,16 @@ The packager refuses a dirty tree, builds the Browser assets and the
linux/amd64 server binary from that exact revision without cgo, records the
full revision, emits a runtime archive plus path/size/SHA-256 manifest and release descriptor, and
extracts its own artifact to verify it. The archive contains exactly
-`screener-server`, `LICENSE`, `THIRD-PARTY-NOTICES.txt`, and `REVISION`. Upload
-the archive, manifest, and descriptor together to `/opt/screener/uploads`.
+`piik-server`, `LICENSE`, `THIRD-PARTY-NOTICES.txt`, and `REVISION`. Upload
+the archive, manifest, and descriptor together to `/opt/piik/uploads`.
The same application descriptor is also the Client assembly input. On each
target platform, provide that platform's Go toolchain:
```sh
-SCREENER_GO=/path/to/go node scripts/assemble-client.mjs \
- /outside/repository/app-release/screener-.release.json \
- /outside/repository/Screener-Client \
+PIIK_GO=/path/to/go node scripts/assemble-client.mjs \
+ /outside/repository/app-release/piik-.release.json \
+ /outside/repository/Piik-Client \
--target windows-amd64 \
--capture /path/to/platform-capture \
--tunnel /path/to/cloudflared
@@ -114,7 +114,7 @@ current CI workflow produces short-lived candidates but does not publish a
GitHub Release; publication remains an explicit distribution decision.
The default Client launcher starts immediately, then performs one background
-request to the official Screener GitHub Releases API. It shows a link only when
+request to the official Piik GitHub Releases API. It shows a link only when
the latest release has a valid full revision different from the packaged one.
The request sends no current revision, credentials, room data, or media data;
network errors, private-repository responses, and missing releases are treated
@@ -127,7 +127,7 @@ bash deploy/check-release.sh
```
The script runs the deployed binary's release check, which reads
-`/opt/screener/current/REVISION` and prints one JSON result.
+`/opt/piik/current/REVISION` and prints one JSON result.
Exit status `0` means the deployed revision is current, `10` means a newer
release is available, and `20` means the check could not establish a valid
release identity. For a private repository, inject a short-lived `GITHUB_TOKEN`
@@ -137,9 +137,11 @@ state. A different current-revision file may be supplied as its only argument.
## Permanent-Room Schema Cutover
-Schema 2 / signaling `screener-v23` requires matching Web/Client/Server builds
-and an accepted active-session interruption. Native control stays v9; Browser
-credential keys stay unchanged. This is not an app-only release.
+The schema 2 / signaling v23 cutover required matching Web/Client/Server builds
+and an accepted active-session interruption. Native control stayed v9; that
+schema change preserved Browser credential keys. It was not an app-only release.
+The separate [brand cutover](./research/piik-rename-plan.md) must preserve this
+database rather than repeat the schema change.
1. Verify the candidate; record the current release, environment, absolute DB
path and ownership. Stop ingress and the old application; take and retain a
@@ -184,21 +186,21 @@ restore the previous infrastructure.
Run the tracked server entry with the uploaded descriptor:
```sh
-sudo env SCREENER_PUBLIC_ORIGIN=https://share.example.com \
+sudo env PIIK_PUBLIC_ORIGIN=https://share.example.com \
bash /path/to/repository/deploy/release-app.sh \
- /opt/screener/uploads/screener-.release.json
+ /opt/piik/uploads/piik-.release.json
```
The wrapper:
1. takes a deployment lock and validates the descriptor, revision, archive,
- manifest, current Go process, Screener/nginx service state, and public origin;
+ manifest, current Go process, Piik/nginx service state, and public origin;
2. rejects unexpected archive paths, links, file types, or duplicate inodes;
3. extracts to a new release directory and verifies every file hash and size;
4. validates production configuration by running the packaged binary's
configuration check as the service user under a bounded runtime;
5. proves the old and new releases share no regular-file inode;
-6. atomically switches `/opt/screener/current`, starts the service, and polls
+6. atomically switches `/opt/piik/current`, starts the service, and polls
bounded local/public health; and
7. restores the exact prior symlink and service when cutover or health fails.
@@ -225,8 +227,8 @@ Verify only the surfaces relevant to the release:
- local and public `/healthz` return `{"status":"ok"}`;
- the public HTML references the new immutable main asset;
-- Screener and nginx have expected active/restart state;
-- Screener owns each configured STUN/SFU UDP listener and public reachability
+- Piik and nginx have expected active/restart state;
+- Piik owns each configured STUN/SFU UDP listener and public reachability
matches the configuration;
- the current symlink and served revision match the descriptor;
- room creation, Host authentication, one direct Viewer, and configured SFU
@@ -240,7 +242,7 @@ to [verification status](./verification-status.md), not routine postflight.
## Recovery
Before cutover, the wrapper keeps the exact prior release path. On failure after
-the switch begins, it stops Screener, restores that path atomically, restarts the
+the switch begins, it stops Piik, restores that path atomically, restarts the
service, and waits for health. A failed recovery exits distinctly and requires
operator intervention; it must not silently report the new release as active.
diff --git a/docs/operations/self-hosting.md b/docs/operations/self-hosting.md
index 0643267..4ad2dcd 100644
--- a/docs/operations/self-hosting.md
+++ b/docs/operations/self-hosting.md
@@ -6,7 +6,7 @@ This runbook owns initial single-host service setup. Application releases use
## Embedded Media Configuration
-The current source embeds STUN and SFU in the Screener process under
+The current source embeds STUN and SFU in the Piik process under
[ADR-0013](../adr/0013-embedded-node-local-media.md). Hosted `STUN_URLS`
advertises ordinary discovery and enables the UDP 3478 listener on
`STUN_LISTEN_HOST` (IPv4, default `0.0.0.0`). Enabling
@@ -16,7 +16,7 @@ public-link Client modes use discovery without creating media-service listeners.
Set `SFU_UDP_PORT=7882` to enable automatic embedded SFU fallback. Its IPv4 bind
address is `SFU_LISTEN_HOST`, default `0.0.0.0`; `SFU_PUBLIC_IP` optionally
overrides the advertised IPv4 address when the host is behind NAT. Unset or
-blank `SFU_UDP_PORT` keeps SFU disabled. SFU control uses authenticated Screener
+blank `SFU_UDP_PORT` keeps SFU disabled. SFU control uses authenticated Piik
signaling through the Web origin. No separate media-service executable, control
origin, or API credentials are needed by this source contract.
@@ -26,27 +26,27 @@ the active-session check, matching artifacts and public media verification below
## Single-Host Topology
```text
-Browser -- HTTPS/WSS --> nginx :443 --> Screener :8787
+Browser -- HTTPS/WSS --> nginx :443 --> Piik :8787
Browser <---------- DTLS-SRTP P2P ----------> Browser
-Browser -------- ordinary STUN/UDP --------> Screener :3478
-Browser -------- optional STUN/UDP --------> Screener :3479/3480
-Browser <--------- DTLS-SRTP/UDP ----------> Screener :7882
+Browser -------- ordinary STUN/UDP --------> Piik :3478
+Browser -------- optional STUN/UDP --------> Piik :3479/3480
+Browser <--------- DTLS-SRTP/UDP ----------> Piik :7882
```
-The public baseline uses one Screener Go binary, nginx, a valid Web TLS
+The public baseline uses one Piik Go binary, nginx, a valid Web TLS
certificate, and time synchronization. nginx terminates Web HTTPS/WSS and
-proxies only to Screener's private application listener; media UDP reaches the
+proxies only to Piik's private application listener; media UDP reaches the
Go process directly. There is no separate SFU token endpoint or TCP 7880 service.
Web and STUN may use different DNS names on the same public IP. Another proxy or
firewall owner needs its own matching updater and recovery checks.
Expose only the public listeners in
-[configuration reference](../reference/configuration.md). Screener TCP 8787 stays
+[configuration reference](../reference/configuration.md). Piik TCP 8787 stays
private. STUN answers Binding requests only; TURN allocations remain unavailable.
## Templates
-- [Screener systemd unit](../../deploy/systemd/screener.service.example)
+- [Piik systemd unit](../../deploy/systemd/piik.service.example)
- [nginx site](../../deploy/nginx/share.bonfire.icu.conf.example)
Copy templates outside the repository, inject independent secrets through an
@@ -56,16 +56,16 @@ domains, certificates, users, and resource limits required by the host.
## Initial Setup
1. Configure DNS and TLS for the Web origin and STUN name.
-2. Install nginx. The Screener release is one static binary and needs no
+2. Install nginx. The Piik release is one static binary and needs no
language runtime or separate media-service executable.
-3. Create an unprivileged `screener` service account, `/opt/screener/releases`,
- `/opt/screener/uploads`, and an access-restricted environment file.
+3. Create an unprivileged `piik` service account, `/opt/piik/releases`,
+ `/opt/piik/uploads`, and an access-restricted environment file.
4. Provision one verified initial immutable release and atomically point
- `/opt/screener/current` to it before enabling the unit. The tracked release
+ `/opt/piik/current` to it before enabling the unit. The tracked release
wrapper is upgrade-only and deliberately refuses a missing prior release;
this repository does not provide a generic first-install transaction.
5. SQLite is the Hosted default. The service template selects
- `/var/lib/screener/rooms.sqlite` in its service-owned StateDirectory; retain
+ `/var/lib/piik/rooms.sqlite` in its service-owned StateDirectory; retain
that absolute path in the environment file and include it in the host's
backup/recovery policy. Use `ROOM_DATABASE_PATH=:memory:` only for intentional
process-only rooms. Do not leave an empty override in a service environment.
@@ -75,7 +75,7 @@ domains, certificates, users, and resource limits required by the host.
preserve the private application boundary.
7. Apply the public-port allowlist and confirm every retired TURN/TCP port
is closed.
-8. Start Screener, then nginx. Screener binds its configured media listeners
+8. Start Piik, then nginx. Piik binds its configured media listeners
before accepting signaling and closes them with the application; a listener
bind failure rolls back startup. Verify public UDP reachability separately.
@@ -93,15 +93,15 @@ proxy/firewall configuration; verify those on the target deployment.
Verify the release archive against its descriptor and manifest using the
[release procedure](../deployment.md), then extract its four files into a new
-build-context directory: `screener-server`, `LICENSE`, `THIRD-PARTY-NOTICES.txt`
+build-context directory: `piik-server`, `LICENSE`, `THIRD-PARTY-NOTICES.txt`
and `REVISION`. Use that directory, not the repository or a secrets directory:
```sh
docker build --platform linux/amd64 \
- -f /path/to/Screener/deploy/container/Dockerfile \
- -t screener: /path/to/extracted-runtime
-docker run --rm --env-file /path/to/screener.env \
- screener: --check-config
+ -f /path/to/Piik/deploy/container/Dockerfile \
+ -t piik: /path/to/extracted-runtime
+docker run --rm --env-file /path/to/piik.env \
+ piik: --check-config
```
Use the existing [production configuration](../reference/configuration.md).
@@ -116,14 +116,14 @@ to a proxy running on the same host. Omit UDP publish options for disabled SFU
or auxiliary STUN listeners; use the matching port if configuration changes it.
```sh
-docker run -d --name screener --restart unless-stopped --stop-timeout 20 \
+docker run -d --name piik --restart unless-stopped --stop-timeout 20 \
--read-only --cap-drop ALL --security-opt no-new-privileges \
- --env-file /path/to/screener.env \
- --mount type=volume,source=screener-data,target=/home/nonroot \
+ --env-file /path/to/piik.env \
+ --mount type=volume,source=piik-data,target=/home/nonroot \
-e ROOM_DATABASE_PATH=/home/nonroot/rooms.sqlite \
-p 127.0.0.1:8787:8787/tcp \
-p 3478:3478/udp -p 3479:3479/udp -p 3480:3480/udp -p 7882:7882/udp \
- screener:
+ piik:
```
The image's `/home/nonroot` is owned by UID/GID `65532:65532` with mode `0700`.
@@ -132,7 +132,7 @@ must already be writable by that identity. Keep this volume when replacing the
container. Set `ROOM_DATABASE_PATH=:memory:` for memory-only room authority. Diagnostics
remain opt-in and use `/home/nonroot/logs`; [export and retention](../reference/configuration.md#diagnostics)
remain the operator's responsibility. Do not mount application files writable.
-With diagnostics enabled, `docker kill --signal=USR1 screener` requests a local
+With diagnostics enabled, `docker kill --signal=USR1 piik` requests a local
export without stopping the container; the ZIP remains in the mounted log directory.
Check `/healthz` from the host and public proxy, then verify configured STUN/SFU
@@ -154,28 +154,28 @@ The routine application wrapper cannot perform or recover it.
Client artifacts. Check active sessions and obtain the owner's acceptance of
share interruption before cutover; old pages and Clients must reload or
update together.
-2. Retain the exact prior release path, Screener unit and drop-ins, environment,
+2. Retain the exact prior release path, Piik unit and drop-ins, environment,
nginx configuration, and external media-service units, configuration, secrets,
and enabled/active state for rollback. Keep this material access-restricted
outside the repository. Define recovery for any persistent-state or firewall
surface the transaction actually changes.
3. Stage the current unit with
- `ExecStart=/opt/screener/current/screener-server` and
- `SCREENER_ENV=production`. Remove retired `NODE_ENV`, `PEER_ASSISTED_MEDIA`
+ `ExecStart=/opt/piik/current/piik-server` and
+ `PIIK_ENV=production`. Remove retired `NODE_ENV`, `PEER_ASSISTED_MEDIA`
and external `LIVEKIT_*` configuration; use the current
[environment contract](../reference/configuration.md), including
`SFU_UDP_PORT=7882` when fallback is enabled. Replace route `NODE_DEBUG` with
- `SCREENER_DEBUG=route` when needed. Validate the new binary's production
+ `PIIK_DEBUG=route` when needed. Validate the new binary's production
configuration as the service user before switching.
-4. Stop Screener and the old coturn/LiveKit services. Disable those old media
- services and remove the installed Screener LiveKit-readiness drop-in so they
+4. Stop Piik and the old coturn/LiveKit services. Disable those old media
+ services and remove the installed Piik LiveKit-readiness drop-in so they
cannot reclaim ports or delay startup. Verify that UDP 3478/3479/3480/7882
are released before the new Go process binds them. Install the current unit,
environment and nginx template, remove the old RTC proxy locations, validate
nginx, and reload systemd. Preserve unrelated proxy headers, limits, TLS,
asset handling, and firewall rules.
5. Atomically point the current release at the verified candidate, start
- Screener, and reload nginx. Verify the actual unit command and environment,
+ Piik, and reload nginx. Verify the actual unit command and environment,
local/public health, the matching Web asset, UDP listener ownership, public
STUN Binding and admitted SFU media, and the agreed active-session outcome.
6. On failure, stop the new Go process and confirm it released its UDP sockets.
@@ -196,11 +196,11 @@ Later application-only releases use the ordinary
Allow UDP 3479 and 3480 in both the cloud security group and the existing
nftables input rule, validating the complete ruleset with
`nft -c -f /etc/nftables.conf`. Set `NAT_PREDICTION_ENABLED=true` and restart
-Screener within an accepted service window. Verify `ss -lunp` shows all three
-Screener STUN listeners and that a public Binding request succeeds on each.
+Piik within an accepted service window. Verify `ss -lunp` shows all three
+Piik STUN listeners and that a public Binding request succeeds on each.
Do not add auxiliary URLs to `STUN_URLS`; enabled connections derive them from
the ordinary STUN authority. Keep both firewall rules while the capability is
-enabled. Set `NAT_PREDICTION_ENABLED=false` and restart Screener before removing
+enabled. Set `NAT_PREDICTION_ENABLED=false` and restart Piik before removing
the auxiliary firewall rules. Avoid verbose STUN/ICE logging because those
requests contain client IP addresses.
@@ -211,15 +211,15 @@ public IPv4.
## Operational Verification
- `/healthz` returns `{"status":"ok"}` locally and through the public origin.
-- Screener and nginx are active with expected restart counts and bounded
- logs/resources; Screener owns the configured STUN/SFU UDP listeners.
+- Piik and nginx are active with expected restart counts and bounded
+ logs/resources; Piik owns the configured STUN/SFU UDP listeners.
- The official Trickle ICE sample obtains an ordinary UDP `srflx` candidate from
the configured STUN service and no relay candidate.
- A direct room presents media on two networks when Peer ICE succeeds.
- A constrained route creates one managed Host publication and only admitted
subscriptions over embedded SFU UDP; Peer descendants remain ordinary P2P.
- Blocking all UDP reaches a clear bounded failure.
-- Restarting Screener in stable mode retains room authority while Browser
+- Restarting Piik in stable mode retains room authority while Browser
sessions and media reconnect from fresh process state.
Representative network, mobile, audio, 20-Viewer, and long-running evidence is
diff --git a/docs/product/media-quality.md b/docs/product/media-quality.md
index b327513..ee89f05 100644
--- a/docs/product/media-quality.md
+++ b/docs/product/media-quality.md
@@ -132,7 +132,7 @@ Each ordinary Browser PeerConnection owns stock WebRTC congestion control and
sender adaptation. Clones share one underlying media source and therefore do not provide
complete simultaneous isolation: framework source-wants aggregation may still
partially reduce frames available to sibling clones. Sibling outputs may differ;
-Screener does not impose a room-wide minimum. The Host's one Browser SFU
+Piik does not impose a room-wide minimum. The Host's one Browser SFU
publication uses the share-generation codec and selected ceilings. Its ordinary
simulcast outputs follow pinned LiveKit screen-share construction: original and
half size at the same frame rate, with a quarter-bitrate lower ceiling and its
@@ -200,7 +200,7 @@ native source. This gives one difficult path stock per-sender adaptation without
lowering the shared representation for healthy paths. It adds no quality score,
timer, or room-wide media setting.
-Screener does not maintain an application bitrate/resolution ladder, scene
+Piik does not maintain an application bitrate/resolution ladder, scene
detector, periodic quality controller, manual SFU layer selector, or
application-defined whole-room lowest-common-denominator target.
diff --git a/docs/product/presentation-lifecycle.md b/docs/product/presentation-lifecycle.md
index 7b278da..c38da24 100644
--- a/docs/product/presentation-lifecycle.md
+++ b/docs/product/presentation-lifecycle.md
@@ -17,7 +17,7 @@ room identity, current state, roster, and one manual media-reconnect action.
Controls and text must remain usable without overlap or horizontal overflow on
desktop and mobile viewports.
-Screener Client opens this same application in the system Browser. Its small
+Piik Client opens this same application in the system Browser. Its small
startup surface selects Local, temporary public invitation, or a configured
Site before entering the Host workspace. Viewer links opened at that activated
origin may use the same running Client without changing the Viewer UI. Starting a share offers the
diff --git a/docs/product/routing-transport.md b/docs/product/routing-transport.md
index 79fc14c..5ba1c1e 100644
--- a/docs/product/routing-transport.md
+++ b/docs/product/routing-transport.md
@@ -128,9 +128,9 @@ SFU offer/answer, ICE and output demand use the existing authenticated room
WebSocket. The server binds each physical connection to the current participant,
share and publication; it issues no separate media token or room-service URL.
Browser SFU PeerConnections use the server's UDP candidates and no external
-ICE-server list. Ordinary peer connections use deployment STUN. Hosted Screener
+ICE-server list. Ordinary peer connections use deployment STUN. Hosted Piik
owns its configured Binding-only STUN listeners and optional SFU UDP listener in
-the same Go process. Screener
+the same Go process. Piik
configures no TURN, ICE/TCP, media TCP, or TLS-relayed media path. HTTPS/WSS is a
separate control transport and remains TLS/TCP.
@@ -151,7 +151,7 @@ the same bounded route recovery. Source capture remains Host-owned throughout.
Browser WebRTC and the shared Pion/LiveKit media adapter own ICE, consent,
congestion control, bitrate, frame rate, resolution, retransmission, pacing and
layer selection. Direct-child media demand does not create a topology operation.
-When the per-share convergence gate is enabled, Screener uses an exact persistent native
+When the per-share convergence gate is enabled, Piik uses an exact persistent native
sender limitation only to trigger one measured experiment through the existing
serial operation. Three fresh complete limited deltas from one exact sender may
trigger that experiment on a newly committed availability or direct-convergence
@@ -181,7 +181,7 @@ frame rate, or bitrate across persistent complete windows and produces no
freeze or pause; otherwise the old Peer route stays. The Host publication
ingress and every Viewer subscription are separate quality paths. One Viewer's
SFU proof never authorizes another Viewer. Disabling the gate leaves quality
-state diagnostic. Screener has no weighted route score, general parent-wide
+state diagnostic. Piik has no weighted route score, general parent-wide
prediction, all-pairs probe, periodic rebalance, persistent parent blacklist,
NAT classification, or independent depth cap.
diff --git a/docs/project-memory.md b/docs/project-memory.md
index 9127b9f..c8c4286 100644
--- a/docs/project-memory.md
+++ b/docs/project-memory.md
@@ -2,7 +2,7 @@
Last updated: 2026-09-10
-Screener is private, low-latency game screen sharing for one Host and up to 20
+Piik is private, low-latency game screen sharing for one Host and up to 20
authenticated friends. The current product surface is Web Host, Web Viewer, and
Browser relay; desktop and mobile Browsers are Viewer targets. It is not a
public broadcast service. Hosted and Client run one shared Go core
@@ -68,7 +68,7 @@ implementation and routine UI detail.
available, and anonymous provenance distinguishes ordinary from predicted
selected paths. The configuration default remains stock ICE. The only
application fallback is one bounded embedded SFU/UDP
- publication; Screener configures no TURN or TCP media route. A pre-share
+ publication; Piik configures no TURN or TCP media route. A pre-share
peer-only policy can exclude that SFU suffix for one share generation.
- Every endpoint shares one steady outbound-copy cap, default `2` and limited to
`1..3`. One room controller owns one committed graph, one reconcile loop, and
@@ -94,12 +94,12 @@ implementation and routine UI detail.
## Current Snapshot
-The permanent-room candidate uses strict `screener-v23` Browser/server signaling,
+The current contract uses strict `piik-v23` Browser/server signaling,
Native control v9 and capture v7 together. Embedded SFU SDP/ICE and demand travel over the
authenticated room WebSocket, without an external room service or media token.
Committed first-frame readiness, bounded candidate-relative progress, durable
room authority and the H.264/VP8 sender gate remain. [Status](./status.md)
-separates this source from last known production; protocol rollback requires
+indexes source and deployment evidence; protocol rollback requires
matching Browser and Client artifacts, not only an application symlink.
Current work is owned by the [TODO ledger](./todo.md). Open physical evidence is
diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md
index 3bf1d70..ef27142 100644
--- a/docs/reference/configuration.md
+++ b/docs/reference/configuration.md
@@ -8,7 +8,7 @@ service secret store or an untracked access-restricted environment file.
| Variable | Contract |
| --- | --- |
-| `SCREENER_ENV` | `development` or `production`, default `development`; required for every server deployment: `production` enables production-only validation and the `Secure` site-access cookie. |
+| `PIIK_ENV` | `development` or `production`, default `development`; required for every server deployment: `production` enables production-only validation and the `Secure` site-access cookie. |
| `LISTEN_HOST` | Defaults to `0.0.0.0`; bare-metal production normally uses `127.0.0.1`. |
| `PORT` | Positive TCP port, default `8787`; the tracked release wrapper supports only that default. |
| `PUBLIC_BASE_URL` | Exact public HTTP(S) origin; production requires HTTPS. |
@@ -35,7 +35,7 @@ public-link Client construction create no SFU listener. The relay does not
provide application E2EE.
The SQLite parent directory must exist and be writable. The systemd template
-sets `/var/lib/screener/rooms.sqlite` under its managed state directory; the
+sets `/var/lib/piik/rooms.sqlite` under its managed state directory; the
container image sets `/home/nonroot/rooms.sqlite` under its writable data
directory. Keep the existing database path and data across application updates.
Room authority has no idle expiry; the separate site-access cookie keeps its
@@ -53,26 +53,26 @@ Diagnostics are local and opt-in. Enable them **before** reproducing the problem
| Surface | Enable | Export |
| --- | --- | --- |
-| Client | Start with `--debug` or `SCREENER_DEBUG=client` | Press `D` in the terminal for a ZIP |
+| Client | Start with `--debug` or `PIIK_DEBUG=client` | Press `D` in the terminal for a ZIP |
| Browser Host/Viewer | Add `?debug=1` to the page URL, before any invitation fragment | Use the download button beside language/theme controls |
-| Hosted Server | Start with `--debug`, `SCREENER_DEBUG=server` or `SCREENER_DEBUG=route` | On Unix, `kill -USR1 `; also exported at orderly shutdown |
+| Hosted Server | Start with `--debug`, `PIIK_DEBUG=server` or `PIIK_DEBUG=route` | On Unix, `kill -USR1 `; also exported at orderly shutdown |
Client/Server ZIP and Browser JSON reports are separate: when investigating
Browser/Client cooperation, include both from the same reproduction. Neither
action stops an active share or uploads anything. Browser export also remains
-available as `await window.__SCREENER_DEBUG__.export()` in DevTools.
+available as `await window.__PIIK_DEBUG__.export()` in DevTools.
-Client logs go to `logs` beside the executable, falling back to `Screener/logs`
+Client logs go to `logs` beside the executable, falling back to `Piik/logs`
in the OS user-cache directory when that default is unwritable. The TUI shows
the actual path and the exported ZIP. `--log-dir` overrides
-`SCREENER_LOG_DIR`; an explicit directory must be writable. Choosing a
+`PIIK_LOG_DIR`; an explicit directory must be writable. Choosing a
directory alone does not enable collection. Non-interactive Clients export at
-orderly shutdown. On Client, `SCREENER_DEBUG=route` alone retains console route
+orderly shutdown. On Client, `PIIK_DEBUG=route` alone retains console route
tracing; use `--debug` for file collection and the `D` action.
-Hosted logs use `SCREENER_LOG_DIR`, otherwise systemd `LOGS_DIRECTORY`,
+Hosted logs use `PIIK_LOG_DIR`, otherwise systemd `LOGS_DIRECTORY`,
otherwise `logs` under the working directory. The service unit supplies
-`/var/log/screener` with mode `0700`. Normal service notices remain in the
+`/var/log/piik` with mode `0700`. Normal service notices remain in the
journal; detailed dependency records go into the report. Windows Server has no
Unix signal trigger; forced process termination cannot create a final snapshot.
@@ -129,10 +129,10 @@ project references and the reasons for this collection boundary.
| Port | Scope | Owner |
| ---: | --- | --- |
| TCP 80/443 | public | HTTP redirect and HTTPS/WSS reverse proxy |
-| UDP 3478 | public | in-process STUN-only Screener listener |
-| UDP 3479/3480 | public when NAT prediction is enabled | in-process auxiliary STUN-only Screener listeners |
-| UDP 7882 (or `SFU_UDP_PORT`) | public when SFU enabled | in-process Screener WebRTC media |
-| TCP 8787 | private | Screener application |
+| UDP 3478 | public | in-process STUN-only Piik listener |
+| UDP 3479/3480 | public when NAT prediction is enabled | in-process auxiliary STUN-only Piik listeners |
+| UDP 7882 (or `SFU_UDP_PORT`) | public when SFU enabled | in-process Piik WebRTC media |
+| TCP 8787 | private | Piik application |
TCP 3478, TCP/TLS 5349, TURN relay ranges, media TCP, and other media
ports remain closed. HTTPS/WSS transport is independent of the UDP-only media
@@ -142,7 +142,7 @@ When `NAT_PREDICTION_ENABLED=true`, the server derives
`stun::3479` and `:3480` from the first ordinary STUN authority
on UDP 3478. The Host sees a pre-share switch that defaults on and may disable
it. The capability adds no media route or third-party service. It needs both
-cloud security-group rules and the host's `/etc/nftables.conf` rule. Screener
+cloud security-group rules and the host's `/etc/nftables.conf` rule. Piik
binds every required UDP listener before opening room persistence or accepting
signaling; a bind failure rolls back all newly owned sockets. Close and End
retire these listeners with the application. Existing coturn listeners must
diff --git a/docs/research/advanced-peer-distribution.md b/docs/research/advanced-peer-distribution.md
index 341d2c6..b552b07 100644
--- a/docs/research/advanced-peer-distribution.md
+++ b/docs/research/advanced-peer-distribution.md
@@ -136,7 +136,7 @@ It has three concrete failures/limits:
- The secondary sender's `framesSent` stayed zero despite sending the complete
payload. Its `qualityLimitationReason=none` is not useful proof that the
- borrowed encoding fits that connection. Existing Screener sender evidence
+ borrowed encoding fits that connection. Existing Piik sender evidence
cannot consume those counters unchanged.
- In a VP8 late-join arm, the secondary received bytes but decoded zero frames
and sent 34 PLI requests. Those requests did not make the primary encoder
diff --git a/docs/research/agent-context-governance.md b/docs/research/agent-context-governance.md
index b2dcc22..cdcef1b 100644
--- a/docs/research/agent-context-governance.md
+++ b/docs/research/agent-context-governance.md
@@ -11,7 +11,7 @@
OpenAI's agent-first repository treats `AGENTS.md` as a map into a structured,
versioned knowledge base. Its reported failure mode for one large instruction
-file is the same one observed in Screener: scarce context is crowded out, every
+file is the same one observed in Piik: scarce context is crowded out, every
rule appears equally important, stale guidance accumulates, and ownership is
hard to verify. The recommended corrective structure is progressive disclosure,
cross-links, and mechanical freshness/structure checks. Codex concatenates the
@@ -34,7 +34,7 @@ below that value and using nested context for genuinely distinct subtrees. Its
bounded-memory guidance starts consolidation at 80% rather than treating the
hard limit as the normal operating target.
-Screener therefore warns at the published recommendation or 80% of a loader
+Piik therefore warns at the published recommendation or 80% of a loader
limit, then fails only at a real loading boundary or a small explicit buffer:
32 KiB for the Codex chain, 20,000 characters for Hermes, and 250 effective
Claude lines above the 200-line recommendation. The same envelope applies to the
@@ -55,7 +55,7 @@ Sources:
### Documentation Shape
Diataxis separates tutorial, how-to, reference, and explanation because mixing
-reader goals makes each form harder to use. Screener's internal product modules
+reader goals makes each form harder to use. Piik's internal product modules
are compact reference; ADRs are explanation of a decision; deployment is a
how-to/reference boundary; research is evidence and explanation. The framework
does not require creating all four categories when there is no reader need.
@@ -76,7 +76,7 @@ Sources:
## Applicability
-Screener is small enough that a vector database, memory provider, generated code
+Piik is small enough that a vector database, memory provider, generated code
map, parallel agent-context format, or separate RFC repository would add more
ownership than it removes. The useful practices are bounded always-on context,
one owner per fact, domain-shaped reference, evidence on demand, short ADRs,
diff --git a/docs/research/backend-audit-1b01048.md b/docs/research/backend-audit-1b01048.md
index 5cbf629..c27c6ee 100644
--- a/docs/research/backend-audit-1b01048.md
+++ b/docs/research/backend-audit-1b01048.md
@@ -49,7 +49,7 @@ bounded graph controller; absent LiveKit configuration still means P2P-only
service. Room privacy and topology-optimization controls remain independent.
The old environment variable must be removed before the next deployment.
There is no Host-star compatibility path to port. Removing the unused
-authentication fields requires the coordinated private `screener-v21` release;
+authentication fields required the coordinated private signaling v21 release;
rollback to the prior server must also restore its environment configuration.
[ADR-0009](../adr/0009-optional-nat-prediction.md) distinguishes server-owned
diff --git a/docs/research/browser-background-capture.md b/docs/research/browser-background-capture.md
index 951c6cd..085d232 100644
--- a/docs/research/browser-background-capture.md
+++ b/docs/research/browser-background-capture.md
@@ -208,4 +208,4 @@ copies no source code and adds no dependency. W3C material uses the
[W3C Document License](https://www.w3.org/copyright/document-license-2023/).
Chromium and WebRTC source files carry BSD-style licenses. Chrome for Developers
prose is CC BY 4.0, with samples under Apache 2.0. These sources are evidence
-only; their implementations are not incorporated into Screener.
+only; their implementations are not incorporated into Piik.
diff --git a/docs/research/cross-platform-client-runtime.md b/docs/research/cross-platform-client-runtime.md
index dbe2692..7fe9e2e 100644
--- a/docs/research/cross-platform-client-runtime.md
+++ b/docs/research/cross-platform-client-runtime.md
@@ -23,7 +23,7 @@ constraint. GameViewer separates its UI, supervised media service, codec
capability detector, streamer, health process, and updater. Discord keeps its
Chromium UI separate from a native voice/media module and updater. Oopz ships
Flutter, a second WebView, FFmpeg, Agora RTC, and Tencent LiteAV together; that
-stack is substantially larger and duplicates media ownership. Screener follows
+stack is substantially larger and duplicates media ownership. Piik follows
the first two products' process separation but not their UI runtimes, and avoids
Oopz's parallel RTC stacks: one Go process, one Pion media core, and one thin
system capture sidecar per platform remain sufficient. No binary code or private
@@ -49,9 +49,9 @@ credentials or route policy; those stay in the Browser/server protocol.
## Client Composition
-The Client and Hosted Screener run the same server core, so the local package is
+The Client and Hosted Piik run the same server core, so the local package is
one executable carrying the built Browser assets plus the optional capture and
-tunnel sidecars; [the Client README](../../cmd/screener-client/README.md) owns
+tunnel sidecars; [the Client README](../../cmd/piik-client/README.md) owns
that layout. In Local mode the Client runs the server in its own process with
explicit local configuration. In Site mode it starts no server, and the system
Browser opens the saved Site while the same process remains its loopback
@@ -67,7 +67,7 @@ Linux remain package gates.
## Local And Hosted Reachability
A local page completed discovery and the full control exchange in Chromium
-151.0.7922.138. The hosted Screener origin completed it after Chromium received
+151.0.7922.138. The hosted Piik origin completed it after Chromium received
its `loopback-network` permission; without that permission the cross-origin
request was blocked. The gate checks both expected outcomes.
@@ -97,7 +97,7 @@ Current WebView2 exposes `getDisplayMedia` screen-capture events and its
Evergreen runtime updates independently; WebKitGTK exposes display capture and
uses GStreamer for WebRTC. Electron instead bundles one Chromium and Node but
makes the Client responsible for shipping those updates and adds substantial
-package size. These facts do not prove equivalent Screener media behavior.
+package size. These facts do not prove equivalent Piik media behavior.
Only a reproduced Browser-launch failure should open a comparative physical
gate for Electron, Tauri, Wails, Neutralino, or another shell. That gate must
@@ -147,7 +147,7 @@ The sidecar remains an explicit package input rather than a linked Client
dependency.
The peer topology gate now treats native `getStats()` RTP identity and frame
-totals as its portable core proof. Detailed Screener quality metrics enrich a
+totals as its portable core proof. Detailed Piik quality metrics enrich a
development run when its source module is served, but their absence on a static
deployment no longer erases valid native RTCStats.
diff --git a/docs/research/embedded-media.md b/docs/research/embedded-media.md
index 189eb3c..3754e05 100644
--- a/docs/research/embedded-media.md
+++ b/docs/research/embedded-media.md
@@ -5,7 +5,7 @@ Baseline: `3da8ecd22a3499e660f498e527ad4ffbaef08c82`.
## Goal
-The owner requests source/library-level STUN and SFU inside the Screener Go
+The owner requests source/library-level STUN and SFU inside the Piik Go
process. Bundled coturn/LiveKit executables, automatic installers, subprocess
supervision and embedding the full LiveKit service do not meet this goal.
The owner has also agreed to [node-local adaptive reuse](./node-local-adaptation.md):
@@ -25,7 +25,7 @@ meet this requirement and is not an SFU replacement candidate.
Retain H264/VP8, Opus, per-subscriber adaptation, retransmission, recovery and
the existing three STUN destinations. Do not trade weak-Viewer experience for a
smaller package, invent an application quality score or add a media ladder.
-The media library, not Screener, must own congestion and layer decisions.
+The media library, not Piik, must own congestion and layer decisions.
No recording, mixing, TURN relay, public port scanning or production test.
Selective local transcoding is now in research scope under the agreed model;
the existing fanout-only probe does not establish that capability.
@@ -53,7 +53,7 @@ because its example compiles. Keep test executables under the worktree's stable
v3 and ICE v2. Do not introduce another older media stack by default.
- inlivedev/sfu uses Pion WebRTC v4 and exposes room/client APIs. Its README
explicitly warns that its API is early-stage; listed features are claims to
- verify, not proof of Screener's required behavior.
+ verify, not proof of Piik's required behavior.
- Galene is useful architectural reference, not yet an accepted library adapter.
## Current Evidence
@@ -91,7 +91,7 @@ Do not add that second transport merely to change the service's name.
WHIP is HTTP signaling for WebRTC ingest, not a replacement media transport.
Its no-renegotiation constraint must be checked against live audio/source changes;
it is not adopted merely because the request/response looks simpler. The current
-Screener signaling owner remains authoritative during this evaluation.
+Piik signaling owner remains authoritative during this evaluation.
## Sources
diff --git a/docs/research/low-server-media-routes.md b/docs/research/low-server-media-routes.md
index a30c693..ebd2f19 100644
--- a/docs/research/low-server-media-routes.md
+++ b/docs/research/low-server-media-routes.md
@@ -140,7 +140,7 @@ that changes this boundary.
Native libp2p, Tailscale, and mobile studies are useful operational evidence,
but their relay reservation, raw-socket control, address discovery, native
coordination, and sampled networks differ from browser WebRTC. Their success
-rates are not Screener coverage estimates.
+rates are not Piik coverage estimates.
## TURN Screening And No-Go
@@ -171,11 +171,11 @@ measured `B_pub` and `sum(B_s)`, so the SFU advantage is not assumed.
This no-go is an application-scope decision, not a claim that TURN is broken.
Coturn remains a valid BSD-3-Clause STUN/TURN implementation, and LiveKit
supports TCP and embedded/external TURN options. Framework capability alone
-does not require enabling every transport in Screener.
+does not require enabling every transport in Piik.
## SFU Admission Evidence
-LiveKit controls do not directly express Screener's resource dimensions:
+LiveKit controls do not directly express Piik's resource dimensions:
- room `maxParticipants` limits participant count;
- `canPublishSources` is an authorization allowlist;
diff --git a/docs/research/native-client-lifecycle.md b/docs/research/native-client-lifecycle.md
index 60d7f9e..5e58dfa 100644
--- a/docs/research/native-client-lifecycle.md
+++ b/docs/research/native-client-lifecycle.md
@@ -208,7 +208,7 @@ extension forcibly disabled **Broadcast IP for Best WebRTC Performance**;
correcting the setting/extension restored Native sharing. The confirmed cause
is that extension's WebRTC policy, not unsupported Windows capture. VPN
extensions may reapply the override; the
-[Chromium WebRTC FAQ](../../cmd/screener-client/README.md#chromium-webrtc-connections)
+[Chromium WebRTC FAQ](../../cmd/piik-client/README.md#chromium-webrtc-connections)
owns the user steps. This does not authorize a Browser-specific transport fallback.
An isolated Chrome 152.0.7977.82 data-channel A/B verifies the policy
diff --git a/docs/research/native-client-media.md b/docs/research/native-client-media.md
index 95392c1..37166de 100644
--- a/docs/research/native-client-media.md
+++ b/docs/research/native-client-media.md
@@ -8,7 +8,7 @@
## Result
-Screener Client can own one process-isolated Windows capture and hardware H.264
+Piik Client can own one process-isolated Windows capture and hardware H.264
encoder, feed its Annex-B access units into one Pion source, and deliver that
source through independent WebRTC transports to unmodified Chrome receivers.
The Browser remains the room, route, and signaling authority.
diff --git a/docs/research/native-sender.md b/docs/research/native-sender.md
index 65bc197..4acb28f 100644
--- a/docs/research/native-sender.md
+++ b/docs/research/native-sender.md
@@ -129,7 +129,7 @@ Before native product consideration, one current-wire candidate must prove:
and
8. project, dependency, H.264 patent, and distribution license decisions.
-No native experiment may preserve an obsolete Screener wire, create another
+No native experiment may preserve an obsolete Piik wire, create another
room/topology model, loosen endpoint capacity, or become production merely to
make a diagnostic gate pass.
diff --git a/docs/research/node-local-adaptation.md b/docs/research/node-local-adaptation.md
index e2a5562..1e34530 100644
--- a/docs/research/node-local-adaptation.md
+++ b/docs/research/node-local-adaptation.md
@@ -16,7 +16,7 @@ alongside an identical `high` encoding.
## Two Workstreams
-- Self-contained Screener Server: library-level STUN/media components inside the
+- Self-contained Piik Server: library-level STUN/media components inside the
executable, not bundled external service processes or an automatic installer.
- Adaptive reuse: local derivation, shared lower outputs, independent child
delivery and quality recovery, usable by Native Client and the server.
@@ -74,7 +74,7 @@ not inferred from the words "automatic" or "simulcast":
counting. Do not claim every unused individual lower layer is always stopped.
- A higher quality request is not subject to downgrade-only debounce. Reduced
maximum demand is debounced; the pinned server default is five seconds. This
- is an upstream implementation fact, not a proposed Screener timing constant.
+ is an upstream implementation fact, not a proposed Piik timing constant.
Publisher deactivation debounce is not a five-second delay before reducing
traffic to a congested subscriber.
- The SDK applies the selected active flags through `RTCRtpSender.setParameters`
@@ -137,7 +137,7 @@ retire their resources immediately; warm retention cannot revive a retired sourc
| Component | Useful capability | Boundary |
| --- | --- | --- |
| Existing `mediaedge.Source` and Pion RTP/WebRTC/interceptors | Encoded fanout, per-edge transport and feedback | No decoder/transcoder or shared-variant policy is supplied automatically |
-| Existing Native encoders and generation/keyframe ownership | Platform encode paths already integrated with Screener | Received-source decode/scale and shared derived outputs still need design |
+| Existing Native encoders and generation/keyframe ownership | Platform encode paths already integrated with Piik | Received-source decode/scale and shared derived outputs still need design |
| LiveKit Dynacast, layer selector and prober sources | Reference for demand aggregation, safe switching and recovery probes | Apache-2.0 code; inspect imports/ownership before any extraction, not whole-service embedding |
| libvpx multi-resolution VP8 API/example | Multiple spatial encodes through one coordinated API; libvpx is already used | VP8-specific; no promise that H264 hardware sessions have the same cost curve |
| OpenH264 AVC simulcast API | Library H264 encode/decode and per-spatial-layer configuration | Software codec; inspect realtime cost and actual source/binary distribution terms before selection |
diff --git a/docs/research/node-local-media-design.md b/docs/research/node-local-media-design.md
index d3a9885..2253ca1 100644
--- a/docs/research/node-local-media-design.md
+++ b/docs/research/node-local-media-design.md
@@ -93,7 +93,7 @@ all layers are distinct costs.
each transport still owns its packet headers and recovery.
5. Reduced demand stops unused upper outputs through the framework's normal
deactivation semantics. Any debounce belongs to that owner, not another
- Screener timer beside it. No application-selected timer values in this draft.
+ Piik timer beside it. No application-selected timer values in this draft.
6. Source replacement/failure/stop invalidates the same generation. No dormant
warm pool survives and no old callback can resurrect an encoder.
@@ -127,8 +127,8 @@ an explicitly controlled input-frame boundary is required. In particular,
| Existing module / primary source | Reuse or learn | Integration limit |
| --- | --- | --- |
-| Screener `mediaedge.Source`, `Edge`, Native capture generations | Encoded-source ownership, Pion connections, existing share/route identity | Static RTP broadcast alone does not solve switching sequence spaces or codec descriptors |
-| [Pion GCC](https://github.com/pion/interceptor/blob/main/pkg/gcc/send_side_bwe.go) and RTP/RTCP interceptors | Existing mature feedback and bandwidth estimate | Current Screener path only observes GCC and uses a no-queue pacer; selection/pacing is not already implemented |
+| Piik `mediaedge.Source`, `Edge`, Native capture generations | Encoded-source ownership, Pion connections, existing share/route identity | Static RTP broadcast alone does not solve switching sequence spaces or codec descriptors |
+| [Pion GCC](https://github.com/pion/interceptor/blob/main/pkg/gcc/send_side_bwe.go) and RTP/RTCP interceptors | Existing mature feedback and bandwidth estimate | Current Piik path only observes GCC and uses a no-queue pacer; selection/pacing is not already implemented |
| [LiveKit Dynacast manager](https://github.com/livekit/livekit/blob/v1.13.6/pkg/rtc/dynacast/dynacastmanagervideo.go) | Highest-needed activation and asymmetric demand handling | Apache-2.0; reference, not import the entire service or its downstream-node aggregation |
| [LiveKit Simulcast selector](https://github.com/livekit/livekit/blob/v1.13.6/pkg/sfu/videolayerselector/simulcast.go), [RTPMunger](https://github.com/livekit/livekit/blob/v1.13.6/pkg/sfu/rtpmunger.go), [prober](https://github.com/livekit/livekit/blob/v1.13.6/pkg/sfu/ccutils/prober.go) | Keyframe switching, packet continuity, bounded recovery probes | Valuable source, but imports protocol/buffer/logger infrastructure; not a demonstrated tiny drop-in |
| [libwebrtc VP8 adapter](https://github.com/webrtc-mirror/webrtc/blob/main/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc) | Coordinated libvpx encoding, SetRates, active-stream keyframes, prepared scale buffers, separate codec and media timestamps | BSD-style; references many WebRTC types. Reuse the underlying libvpx API before copying a large wrapper |
@@ -141,7 +141,7 @@ or a proved adaptation replacement. Its inspected layer sender is coupled to
Client, track, bitrate-controller and packet-map owners; don't copy it as an
independent universal selector. No new dependency or upstream implementation
source was copied in this design pass. Preserve upstream licenses/notices when
-an actual module is chosen; Screener's MIT does not replace them.
+an actual module is chosen; Piik's MIT does not replace them.
Parallel inLive API inspection found work to validate before selecting it:
publisher-demand change notification is not public; `AddRelayTrack` installs a
@@ -149,7 +149,7 @@ no-op PLI callback; the layer sender has its own packet mapping rather than a
standalone codec-neutral switch API. Its inspected timestamp expression subtracts
the layer origin twice. Manager room removal/locking, failed-PC closing and
logger injection also need focused reproductions. These are candidate-library
-risks, not claims about deployed Screener bugs or reasons to expand the Native
+risks, not claims about deployed Piik bugs or reasons to expand the Native
module into an SFU fork.
## Required Before Production
@@ -354,7 +354,7 @@ compare the selected complete media adapter against the same release trace.
Run the probe explicitly from the repository root, optionally with
`-frame-bursts`; it writes only ignored `build/embedded-media` diagnostics. It is
not a default unit/CI task. The observed cadence sensitivity is a reason to test
-the real packet path, not to introduce a Screener congestion score.
+the real packet path, not to introduce a Piik congestion score.
### Embedded Service Composition
@@ -372,7 +372,7 @@ the existing Close/End owner retires STUN too. No service supervisor or second
availability flag is needed. Deployment removes coturn in the final coordinated
cutover, not while the media implementation is still under acceptance.
-The implementation candidate uses a thin Screener SFU with LiveKit **media-core
+The implementation candidate uses a thin Piik SFU with LiveKit **media-core
components**, without its RTC room or service. A stock-Pion compile and actual
ReceiverBase/DownTrack projection pass; two receiving PCs also demonstrate an
unaffected high-output sibling and high/low/high allocation under forced budgets.
@@ -463,8 +463,8 @@ and the existing pinned libvpx build, using the same MSVC flags as the earlier
CPU probe. Generate its JSONL under `build/embedded-media`, then run:
```powershell
-$env:SCREENER_ENCODED_FIXTURE = 'build/embedded-media/encoded-group.fixture.jsonl'
-$env:SCREENER_ENCODED_OUTPUT = 'build/embedded-media/encoded-group.received.json'
+$env:PIIK_ENCODED_FIXTURE = 'build/embedded-media/encoded-group.fixture.jsonl'
+$env:PIIK_ENCODED_OUTPUT = 'build/embedded-media/encoded-group.received.json'
& .\build\embedded-media\mediaedge.test.exe '-test.run=TestEncodedGroupVP8Fixture' '-test.v' '-test.timeout=30s'
node scripts/encoded-group-decode.mjs
```
diff --git a/docs/research/piik-rename-plan.md b/docs/research/piik-rename-plan.md
new file mode 100644
index 0000000..ee5dba7
--- /dev/null
+++ b/docs/research/piik-rename-plan.md
@@ -0,0 +1,141 @@
+# Piik rename
+
+Status: accepted rename and coordinated cutover plan.
+Last reviewed: 2026-09-10.
+
+## Accepted identity
+
+Display `Piik`; use `piik` for executable, package, environment and service
+identifiers. GitHub is `TNTcraftHIM/Piik`; the Go module follows that exact case.
+The native macOS bundle identifier is `tv.piik.client`.
+The product keeps its TV mascot. The wordmark and morph animation remain in the
+[brand study](../design/piik-brand.html) for the future public website.
+
+This is a private pre-release rename. It changes names and deployment identity,
+not media policy, routing, capture behavior or SQLite room semantics.
+
+## Recovery and local metadata
+
+The external `Piik-recovery/rename-20260910` directory contains a verified
+`repository.bundle` and a complete `git-metadata` copy. The latter preserves
+reflogs and all ten stash entries, which a bundle of ordinary refs alone does
+not capture. Earlier recovery bundles also remain outside the repository.
+Backups keep their original names and contents so they remain identifiable.
+
+The main directory is `Piik`; preparation worktrees are `Piik-appearance` and
+`Piik-rename`, with `Piik-external-audit` retained separately. Their private Git
+registration names, backlinks and shared remote are updated. The hook path is
+relative `.githooks`. Retire integrated preparation worktrees after cutover.
+The audit worktree's branch and source revision remain untouched. Integration
+keeps one complete phase commit on main.
+
+On Windows, a terminal can hold the repository directory open. Move the entries
+into an empty verified destination and run `git worktree repair` from the new
+main directory. Do not terminate the user's terminal to release a path.
+Existing firewall rules name executable paths, so moved build binaries require
+their corresponding path rules to be reviewed before network acceptance.
+
+## Runtime and data boundary
+
+`piik-v23` and `piik-client-v9` are new exact protocol labels. Their message
+schemas retain versions 23 and 9; the full label, not only its numeric suffix,
+is checked. Native capture remains v7. Release Web, Server, Client and capture
+artifacts together; old pages and installed Clients cannot interoperate across
+the renamed control boundary. No alternate protocol reader is introduced.
+
+SQLite schema 2, its application ID, room codes, token/grant digests and password
+material remain unchanged. The four-byte database file identity is a format
+constant, not display branding. Copy the database only while the old process is
+stopped, verify integrity and retained columns, and preserve the original for
+rollback. Do not recreate rooms or repeat the earlier schema-1 cutover.
+
+The implementation renames Browser storage prefixes, the site-access cookie
+and the Client configuration/cache directory. The owner accepts a clean break:
+copy directly compatible, accessible settings once during cutover; discard
+unavailable or incompatible settings. The product reads only Piik names, with
+no migration code, alternate reader or old-name alias.
+
+The local Client configuration is unchanged JSON version 1 and can be copied
+byte-for-byte into the Piik directory without replacing an existing new config.
+Browser credentials and settings are origin/session-owned. Transfer them only
+through an available original Browser session; do not modify a live Browser's
+storage database or introduce a product bridge to recover them. Otherwise the
+new namespace starts empty, requiring login, room creation and preference setup.
+Old room authority remains in SQLite, but an unavailable Host credential cannot
+be reconstructed from its stored digest. Site-access cookies and remembered
+Client activation are renewed normally under the new contract.
+
+## Git history
+
+The owner authorized replacing the old name in Git history. Use the maintained
+`git-filter-repo` tool in a fresh, separate bare clone, never in the working
+repository. Scope this to commit/tag **messages**: historical source snapshots,
+authorship, dates and topology remain factual. Current tracked prose and code
+use the accepted identity; old snapshots remain recoverable at their mapped
+commits and in the original archive.
+
+The initial inventory found two matching commit bodies and no matching commit
+subjects or tag names. A small text change still changes descendant SHAs and
+invalidates their commit signatures. Preserve `commit-map` and `ref-map`; verify
+equal commit counts, identical source trees, mapped parents, authors and dates,
+no dropped commits and a clean repository integrity check. No replacement refs,
+duplicate compatibility branches or history-rewriting tool enter the product.
+
+The rehearsal verified all 546 reachable branch/tag commits: exactly two messages
+changed, all file trees and mapped parent relationships match, and authors/dates
+are preserved. Standard filtering rewrote 545 IDs and removed 374 signatures.
+Those signatures remain verifiable only in the original archive; a rewritten
+commit must not be presented as preserving its earlier GitHub verification.
+
+Apply a reviewed message rewrite only with the coordinated brand integration,
+using explicit ref targets and old-SHA leases. Do not use `push --mirror` from
+the rehearsal: it could overwrite unrelated refs. Preserve the external audit
+branch and stash history in the original repository. Old audit/deployment SHAs
+remain evidence identifiers, interpreted through the archive and commit map.
+
+## Operational cutover
+
+The following old identifiers are retained here only as operator recovery
+inputs, not as runtime aliases:
+
+| Surface | Before | After |
+| --- | --- | --- |
+| Service, user and group | `screener` | `piik` |
+| Installation root | `/opt/screener` | `/opt/piik` |
+| Environment file | `/etc/screener/screener.env` | `/etc/piik/piik.env` |
+| Branded environment prefix | `SCREENER_` | `PIIK_` |
+| Browser storage prefix | `screener:` | `piik:` |
+| Client config directory | `Screener` | `Piik` |
+
+Prepare the new immutable artifacts, service/environment/proxy configuration,
+permissions and database path before stopping the old service. Record original
+configuration and ownership for recovery. Do not run two room authorities on
+the same database or two media services on the same UDP ports.
+
+The routine `deploy/release-app.sh` assumes an existing **Piik** installation.
+It is not the first brand migration tool: its old-release checks and recovery
+target the Piik service/binary. Perform the first name cutover as one explicit
+infrastructure operation, then use the ordinary wrapper for future releases.
+On failure, stop the candidate and restore the old binary, service, environment,
+proxy and data together before reopening ingress.
+
+GitHub is already renamed and the remote works. There are no published releases
+or Pages site to migrate. Keep repository visibility private; `piik.tv` DNS and
+Pages publication remain a separate website task. Old GitHub deployment/PR
+records describe earlier operations and are not rewritten as new releases.
+
+## Validation and references
+
+Acceptance covers the tracked-name inventory, Web type/build checks, relevant
+contract/storage tests, native compilation, Client/Server packaging and a
+controlled local launch. Production release additionally requires the accepted
+best-effort settings transfer, configuration/database recovery and postflight.
+
+Primary references, checked 2026-09-10:
+
+- [Git worktree repair](https://git-scm.com/docs/git-worktree): repair both
+ directions after moving the main repository or linked worktrees.
+- [git-filter-repo](https://github.com/newren/git-filter-repo/blob/main/Documentation/git-filter-repo.txt):
+ message replacement, fresh clones and old/new commit maps.
+- [GitHub repository rename](https://docs.github.com/en/repositories/creating-and-managing-repositories/renaming-a-repository):
+ ordinary URL redirects do not cover repository-hosted Actions or project Pages.
diff --git a/docs/research/platform-output.md b/docs/research/platform-output.md
index c905304..b572678 100644
--- a/docs/research/platform-output.md
+++ b/docs/research/platform-output.md
@@ -2,18 +2,18 @@
Last reviewed: 2026-08-31
-This document owns evidence for showing a live Screener session on an AirPlay,
+This document owns evidence for showing a live Piik session on an AirPlay,
Cast, or Presentation API display. It does not add a product output surface.
## Current Decision
Do not add an application Cast or AirPlay button yet. Browser or operating-system
-tab/screen mirroring is already usable without Screener integration. The Web
+tab/screen mirroring is already usable without Piik integration. The Web
platform does not give the current `video.srcObject = MediaStream` a portable
remote-playback contract.
The only application design worth a physical prototype is a custom Cast
-receiver acting as another authenticated Screener Viewer. It would receive its
+receiver acting as another authenticated Piik Viewer. It would receive its
own WebRTC route and count toward room and endpoint capacity; it would not reuse
or fling the controlling Browser's decoded video element.
@@ -24,7 +24,7 @@ or fling the controlling Browser's decoded video element.
Browser and operating-system UI can mirror a tab, window, screen, or media
element. The W3C Remote Playback model explicitly permits this implementation
shape but does not standardize its transport, latency, quality, lifecycle, or
-device coverage. Screener needs no adapter for it and cannot claim its result.
+device coverage. Piik needs no adapter for it and cannot claim its result.
### Media Remoting Or Flinging
@@ -55,12 +55,12 @@ application with custom messaging.
That makes a narrow architecture possible: launch a receiver page, deliver a
short-lived room-scoped Viewer grant over the established control channel, and
-let that page join through the normal Screener Viewer and routing contracts. The
+let that page join through the normal Piik Viewer and routing contracts. The
grant must not appear in the presentation URL, logs, storage, or device metadata.
This is not accepted product behavior. Google's documented media matrix does
not promise WebRTC in a Custom Web Receiver, the Presentation API is not a
-cross-Browser surface, and no target receiver has proved Screener's codec,
+cross-Browser surface, and no target receiver has proved Piik's codec,
autoplay, audio, network, or lifecycle requirements.
## Physical Acceptance Gate
diff --git a/docs/research/realtime-quality-adaptation.md b/docs/research/realtime-quality-adaptation.md
index 44c2510..25bcda6 100644
--- a/docs/research/realtime-quality-adaptation.md
+++ b/docs/research/realtime-quality-adaptation.md
@@ -230,7 +230,7 @@ default screen-share publication can expose original and lower representations,
and server BWE can forward a lower representation to a constrained subscriber
while another receives the highest available representation.
-Calling the pinned client's own encoding calculator with Screener's exact
+Calling the pinned client's own encoding calculator with Piik's exact
publish options produces two VP8 encodings for every accepted profile:
| Profile | Lower representation | Original representation |
@@ -239,7 +239,7 @@ publish options produces two VP8 encodings for every accepted profile:
| 1080p30 | 1/2 scale, 1.25 Mbps, 30 fps | 5 Mbps, 30 fps |
| 1080p60 | 1/2 scale, 2 Mbps, 60 fps | 8 Mbps, 60 fps |
-Both encodings start without an explicit RTP `priority` because Screener's
+Both encodings start without an explicit RTP `priority` because Piik's
custom `screenShareEncoding` replaces LiveKit's priority-bearing preset while
retaining its default `simulcast: true`. The audio encoding is `high` priority.
Priority can only redistribute bandwidth within that PeerConnection and request
diff --git a/docs/research/server-consolidation.md b/docs/research/server-consolidation.md
index eee7ede..42917d8 100644
--- a/docs/research/server-consolidation.md
+++ b/docs/research/server-consolidation.md
@@ -7,7 +7,7 @@
## Current Ownership
-`cmd/screener-server` (Hosted) and `cmd/screener-client` (Client) compose the
+`cmd/piik-server` (Hosted) and `cmd/piik-client` (Client) compose the
same application from `internal/server` and own only their defaults,
reachability, and lifecycle policy. Within that scope `protocol` owns wire types,
strict decoding, and shared scalars; `config` owns environment validation plus
@@ -46,8 +46,8 @@ share one route authority and LiveKit remains an optional fallback of that graph
```text
one Go module
-cmd/screener-server -> shared server application
-cmd/screener-client -> shared server application + launcher + native media
+cmd/piik-server -> shared server application
+cmd/piik-client -> shared server application + launcher + native media
internal/server -> rooms, routing, HTTP/signaling, persistence, SFU adapters
internal/client -> current native and platform boundaries
one React/Vite static artifact -> embedded in both binaries
@@ -106,7 +106,7 @@ origin, site-access password, one STUN URL, loopback listen host), polled
`/healthz` every 10 ms until `{"status":"ok"}`, waited 5 s idle, sampled
resident memory through PowerShell `WorkingSet64`, then killed the process.
Five runs per side; the median is reported. Before is the Node baseline at tag
-`baseline-b20fd88`; after is `screener-server` under the same script.
+`baseline-b20fd88`; after is `piik-server` under the same script.
| metric | before | after |
| --- | ---: | ---: |
@@ -117,9 +117,9 @@ Five runs per side; the median is reported. Before is the Node baseline at tag
The before total is the Node runtime (91,694,408 B), the production
`node_modules` tree (12,640,469 B in 1,513 files), `dist/client` (1,492,721 B)
and `dist/server` (856,898 B). The after total is the linux/amd64
-`screener-server` built with `-s -w` and embedded assets (13,983,906 B) plus its
+`piik-server` built with `-s -w` and embedded assets (13,983,906 B) plus its
notices and `REVISION`. For reference, the windows/amd64 binaries are
-14,276,608 B (`screener-server`) and 22,703,104 B (`screener-client`, which also
+14,276,608 B (`piik-server`) and 22,703,104 B (`piik-client`, which also
carries Pion and the terminal UI); the Client package additionally drops the
Node runtime and dependency tree it used to ship beside its Go executable.
diff --git a/docs/research/webrtc-encoder-pool.md b/docs/research/webrtc-encoder-pool.md
index 28166a1..bb042a0 100644
--- a/docs/research/webrtc-encoder-pool.md
+++ b/docs/research/webrtc-encoder-pool.md
@@ -13,7 +13,7 @@ The installed Chrome is 152.0.7977.82. Its [DEPS][chromium-deps] pins libwebrtc
to `6f37672d358475cd17544121a12494da454d85fb`; WebRTC references below use that
revision, not a floating upstream branch. Source shows available mechanisms,
not which field trials or hardware encoder a particular runtime selected.
-The Screener comparison uses the `3c192ddd` candidate, not production.
+The Piik comparison uses the `3c192ddd` candidate, not production.
## Actual Control Ownership
@@ -45,7 +45,7 @@ These are connected but different owners:
For example, the adapter can request at most 3/5 of the current pixel count or
reduce FPS to 2/3 under the corresponding preference. These are upstream rules,
-not proposed Screener constants. The default [encoder minimum][encoder-api] is
+not proposed Piik constants. The default [encoder minimum][encoder-api] is
320x180 pixels and can be overridden; no universal 108p floor is established.
VP8's [libvpx adapter][vp8] disables libvpx internal resizing because WebRTC owns
that work outside the codec. Turning on libvpx resizing alone does not restore
@@ -53,7 +53,7 @@ the omitted control chain.
### Motion And Simulcast Are Not Synonyms
-Screener's `motion` hint becomes `kFluid` in the [Chromium sink][chromium-hint].
+Piik's `motion` hint becomes `kFluid` in the [Chromium sink][chromium-hint].
[VideoRtpSender][sender-hint] then sets `is_screencast=false`; this follows the
realtime-video path even for display capture. Explicit degradation preference
still has precedence over the hint's default. Do not assume all display capture
@@ -584,7 +584,7 @@ software encoder. VSE invokes `OnEncodeStarted` on its encoder queue just
before the codec call; raw arrival and `OnDiscardedFrame` do not supply CPU
samples. Replaying dropped inputs as encoded work would misrepresent feedback.
-Screener's synchronous drain and latest-input mailbox reduce arrivals into VSE
+Piik's synchronous drain and latest-input mailbox reduce arrivals into VSE
under this load, but the [same pinned VSE][vse] also skips queued frames before
calling the CPU observer. Therefore moving admission or reporting source drops
alone is not an established fix for multi-second encode gaps. Chromium's pinned
diff --git a/docs/status.md b/docs/status.md
index 726e41a..7c6cc56 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -23,21 +23,24 @@ and Git/PRs own completed history.
## Deployment
-The owner authorized integration, coordinated cutover and cleanup before the
-Piik appearance phase. Authorization is not deployment evidence: the immutable
-release descriptor, runtime `REVISION` and operator deployment record own the
-actual deployed identity and postflight result. The
-[schema cutover procedure](./deployment.md#permanent-room-schema-cutover) preserves
-existing room authority and Browser credential keys with a database/application
-rollback boundary.
+Source, package identity, GitHub repository and local worktree paths use Piik.
+The strict wire labels and stored keys move together at the coordinated
+[brand cutover](./research/piik-rename-plan.md). Directly compatible, accessible
+settings are transferred once; unavailable settings start fresh. Runtime code
+keeps only the Piik contract.
+The immutable release descriptor, runtime `REVISION` and operator deployment
+record own exact identity and postflight results. The
+[schema cutover](./deployment.md#permanent-room-schema-cutover) preserved existing
+room authority and Browser credential keys. Old active pages reload at the
+signaling v23 boundary.
The existing deployment uses one Go process for Web, room authority/signaling,
Binding-only STUN on UDP 3478/3479/3480 and optional SFU on UDP 7882. nginx owns
HTTPS; external LiveKit/coturn services remain disabled. Participants, routes and
media remain process-only. This private service is not a public demonstration.
-[TODO](./todo.md) owns closeout and subsequent appearance, renaming, distribution
-and ablation work. No public site or bulk rename belongs to this release.
+[TODO](./todo.md) owns rename acceptance, distribution and ablation work.
+The public website is a later phase.
## Media Evidence And Limits
diff --git a/docs/todo.md b/docs/todo.md
index 298245f..77ada5e 100644
--- a/docs/todo.md
+++ b/docs/todo.md
@@ -7,43 +7,19 @@ and Git/PRs own completed history. A parked idea is not implementation authority
## Now
-Finish the owner-authorized PR386 squash, matched Web/Client/Server cutover and
-cleanup, then resume Piik appearance. Entry/Client lifecycle repairs, confirmed
-reconnect ownership fixes and the permanent-room/Hosted SQLite-default revision
-are implemented and verified. Product modules and
-[ADR-0002](./adr/0002-memory-resident-protected-rooms.md) own that accepted behavior.
-
-Use the [coordinated cutover](./deployment.md#permanent-room-schema-cutover) to
-preserve existing SQLite authority and unchanged Browser credential keys; old
-active pages reload at the signaling v23 boundary. Runtime release metadata and
-the operator record own deployment completion. Do not recreate databases or
-add a replacement garbage collector. Later manual feedback is nonblocking.
+No further product implementation is queued for the accepted Piik rename.
+Its coordinated Web/Client/Server and Git-history cutover follows the
+[rename plan](./research/piik-rename-plan.md); the immutable release descriptor
+and deployment record own rollout identity. Preserve the original repository
+backup and external-audit worktree. Website work starts on owner direction.
## Next — Awaiting Owner Direction
-1. Resume the [Piik brand study](./design/piik-brand.html) after the experience
- repairs. Keep round i dots; the tiny-e experiment was rejected. Try using the
- two outer stems as small headphones/earcups on the TV, retaining its familiar
- silhouette and the k diagonals as antennae. Display `Piik` and technical
- `piik` remain proposals. Settle identity before coordinated renaming or the
- public-site implementation.
-2. After the brand discussion, rename display copy, Go/npm source identity,
- Client/Server packages and OS icons, strict protocol/service identifiers,
- diagnostic redaction, configuration and deployment tooling in one coordinated
- phase. Inventory is complete. Browser storage contains room authority/grants
- and Client configuration contains a saved Site; decide preservation/reset
- explicitly before renaming their keys or directories. Preserve SQLite room
- authority when changing deployment paths. Use matching Web/Client/Server
- artifacts and one current reader/writer, without compatibility aliases.
- Keep third-party names/notices and historical evidence attribution accurate.
-
The owner owns **piik.tv**.
-Agree on casing, TV mascot/wordmark treatment, repository and runtime identifiers,
-release names and the GitHub Pages website before implementing the rename.
-Keep one current internal contract and remove replaced names in the coordinated
-change; no private compatibility aliases. Existing sketches are input, not an
-accepted identity. Do not configure DNS/Pages or publish the brand before that
-design discussion. The private production service is not a public demo.
+Design the GitHub Pages website around the accepted brand study. Keep one
+current internal contract; third-party names/notices remain accurate. DNS/Pages
+and public publication are separate from the repository rename. The private
+production service is not a public demo.
Include the owner-requested frontend/backend ablation review in that phase.
Review duplicated behavior/state, module boundaries, interface clarity, lifecycle
diff --git a/go.mod b/go.mod
index 88d1fd9..f0cd37a 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/TNTcraftHIM/Screener
+module github.com/TNTcraftHIM/Piik
go 1.26
diff --git a/index.html b/index.html
index 8c7b31e..a5f7873 100644
--- a/index.html
+++ b/index.html
@@ -6,10 +6,10 @@
- Screener
+ Piik