dumbtv
dumbtv takes the ads, screen tracking and update nags out of your Fire TV over ADB. No root, none of your apps touched, every step can be undone. Free and open source.
Nook is an open-source, client-side password and secrets manager for encrypted vaults that stay under your control.
SecurityTypeScript · RustGitHub @meta-secretOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Decentralized Offline Secret Manager
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Nook is a passwordless, local-first secrets manager. Your vault is encrypted in the browser, replicated only through storage you choose, and opened only by identities you authorize.
Nook's k8s and k0s automation is Kubernetes-native: cluster Pods never run or control Docker, Podman, DinD, or another nested container runtime. BuildKit is build-only, and browser tests execute directly inside purpose-built Pods. The local-machine runtime policy remains intentionally undecided.
There is no centrally hosted Nook account and no master password. The shipped applications keep multiple local identities in an independently protected browser keyring. Replicated identity control remains target architecture; identity records are not owned by a Nook account service. See the identity and vault architecture for the implemented/target boundary.
[!WARNING] Nook is early-stage software. Vault formats and workflows may still change. Do not use it as the only copy of important credentials or recovery phrases.
| Vault | Best for | URL |
|---|---|---|
| Simple | Everyday passwords and secrets | simple.nokey.sh |
| Sentinel | Quorum-protected high-value secrets | sentinel.nokey.sh |
They are independent applications and browser origins, not modes in one app. The browser extension pairs only with Simple Vault.
After you pick a product, the first-device screen offers two intents: create a new vault, or connect a sync provider for an existing compatible vault.
Most password managers give you one master password. You must remember it. It can be phished. Lose it, and you may lose the vault.
Nook replaces that with device keys and deliberate consent:
Unlock this browser with a passkey (WebAuthn PRF) or PIN fallback. GitHub,
Google Drive, iCloud, and local-folder sync are available today; more providers
are planned. Google Drive syncs through one folder named Nook in your My
Drive, each vault in its own subfolder; iCloud syncs through a share. You
authorize other accounts on that folder or share — a device invite names one
authorized account and carries only the share target; each browser signs in
independently.
One trade-off: if you lose every approved device (and any recovery path you configured), you lose the vault. Approve at least two devices.
| Type | Fields |
|---|---|
| Login | Website URL, username, password, optional notes |
| API key | Website URL, key, optional expiration date |
| BIP39 seed phrase | Account name, seed phrase |
| Secure note | Title, note (Markdown) |
| Passkey | Website/RP and account metadata; encrypted ES256 credential |
| Authenticator | Service, account, and TOTP setup key or otpauth:// URI; browser extension can also enroll from a consented setup-page QR or visible setup key and attach reviewed backup codes |
Items are searchable through a browser-local encrypted catalog of list fields. The catalog is decrypted into WASM memory only while the vault is unlocked. Passwords, API keys, note bodies, seed phrases, full card numbers, OTP seeds, passkey private keys, backup codes, and file contents are excluded. Secret values stay masked until revealed. Authenticator items derive the current one-time code locally in Rust/WASM and never persist generated codes. Nook also includes a secure password generator.
Supported vault items can be edited in place. Replacement validation, encryption, and persistence stay in Rust/WASM. Passkey private material remains non-editable.
Add Nook to Chrome or Brave for permissioned password filling, TOTP auto-fill, and passkey use from an approved, unlocked Simple Vault.
The extension is a separately protected device. It pairs only with Simple Vault; Sentinel never participates. Passkey generation, RP validation, signing, and counter updates stay in Rust/WASM. On recognized one-time-code fields, the user searches and chooses from all saved authenticator items in an extension-owned 2FA picker, and the extension fills a freshly derived code. Issuer and account labels never enter the website DOM. Setup-page QR and setup-key enrollment and backup-code capture require the same explicit Pilot consent and confirmation before anything is saved.
The extension keeps its own encrypted vault projection, pairing grants, and sync-provider grants in extension-owned IndexedDB. Clearing website-local vault data does not erase or revoke that independent extension device. Reopening the same vault store reconnects it automatically; opening a different vault shows the extension's current vault identity and requires an explicit, valid switch.
Production installs through the Chrome Web Store (Brave uses the same listing). Development and PR previews offer an unsigned ZIP with Developer-mode install instructions; see Deployments.
| Source | Format | What imports |
|---|---|---|
| Bitwarden | JSON (plaintext or password-protected) | Logins, secure notes, credit cards |
| LastPass | Unencrypted generic CSV | Logins, secure notes |
| Keeper | Unencrypted CSV | Logins, secure notes |
| 1Password | Unencrypted 1PUX | Logins, passwords, secure notes, credit cards |
| Apple Passwords | Unencrypted CSV | Website logins, TOTP |
| Chrome / Chromium / Brave / Edge | Unencrypted password CSV | Website logins |
| Proton Pass | Unencrypted ZIP or decrypted data.json | Logins, secure notes, credit cards |
| Google Authenticator | Migration QR codes (camera or images) | TOTP accounts |
Unsupported item types and attachments are skipped. Account-restricted Bitwarden exports are not portable. PGP-encrypted Proton Pass exports must be decrypted first.
Overlapping records reconcile with vault-keyed item-identity and secret-version HMAC fingerprints. Matching secret versions enrich the existing item; differing passwords stay as separate items instead of being overwritten.
Open Devices & access from the login screen or the authenticated Access tab. The identity rail lists every independently protected local identity. Add identity opens the browser-protection widget and atomically adds a new passkey- or PIN-protected app key. Selecting another local identity clears the prior vault and provider session, then requires that identity to authenticate. The passkey row owns its inline rename action; browser ceremony diagnostics are not part of the primary page. The page remains useful before a vault exists and while every vault is locked. See the product specification for the access model and honest limits on passkey-provider visibility.
| Layer | What it does |
|---|---|
| Local identity keyring | Each local identity owns one independently wrapped X25519 app key and an app-key-sealed event-signing seed. Plaintext exists only while unlocked. |
| Identity directory | Records local identities, the selected identity, public app-key membership, and locally known vault grants. |
| Key envelopes | Vault keys are wrapped per authorized app key so approved installations unlock secrets without a central authority. |
| Sync transport | Optional providers move encrypted vault events; app-ID-scoped credentials cannot cross an identity transition. |
| Event log | Content-addressed, signed events form a causal DAG so replicas converge without a central sequencer. |
The shipped browser stores a local identity directory, selected identity, and
local_identity_keyring_v1. It migrates the former singleton wrapped app key
and event-signing seed into the selected identity on first use.
Local encrypted identity-to-vault grants are implemented for Simple vaults.
Replicated identity control, replicated grant enforcement, and virtual-identity
association for quorum-protected Sentinel vaults remain future work.
local command
→ signed encrypted event
→ IndexedDB event store
↔ set union ↔ GitHub (nook-log/v1/events/…)
→ causal DAG + deterministic projection
→ encrypted session + encrypted local search catalog
→ one-record plaintext exposure on reveal/copy (unlocked only)
Cryptography and domain logic run in Rust compiled to WebAssembly. Secret payloads are typed YAML encrypted with age.
App code lives under nook-app/. Dependencies flow one way:
nook-vault-simple / nook-vault-sentinel / nook-web-extension
├─> nook-wasm browser I/O + full vault session bridge
│ ├─> nook-core vault application services, secrets, sync policy
│ │ ├─> nook-authenticator-domain
│ │ ├─> nook-event-log
│ │ │ ├─> nook-auth2
│ │ │ └─> nook-replication
│ │ └─> nook-app-common
│ └─> nook-companion-core
│ ├─> nook-authenticator-domain
│ └─> nook-event-log
└─> nook-companion-wasm size-sensitive extension policy bridge
└─> nook-companion-core
nook-auth2 ─┬─> nook-authenticator-domain
└─> nook-app-common
nook-app-common is a leaf dependency used directly by both nook-auth2 and
nook-core; it does not sit between the event-log and replication layers.
| Package | Role |
|---|---|
nook-app-common | Dependency-light shared Rust primitives, locale catalogs, translation behavior, and the single generated Rust i18n key registry |
nook-authenticator-domain | Dependency-light closed values for passkey protection, TOTP metadata, and backup-code update policy shared across authentication, vault, and extension boundaries |
nook-auth2 | Portable identity and key access: identity directories, local keyring invariants, app keys, age envelopes, and recovery helpers |
nook-replication | Portable replication: causal DAG indexing, append-only replica sets, outbox and repair planning |
nook-event-log | Portable vault history: canonical signed events, actor authorization, deterministic projection, key epochs |
nook-core | Vault application domain: typed plaintext secrets, encryption workflows, provider-neutral sync and session policy |
nook-companion-core | Portable extension policy: authentication workflow, pairing records and migration, host and field classification |
nook-companion-wasm | Small wasm-bindgen bridge exposing companion policy to extension contexts |
nook-wasm | Full wasm-bindgen bridge, IndexedDB keyring/provider persistence, remote-provider I/O, and identity-scoped session manager |
nook-vault-simple | Independent Svelte 5 Simple Vault application |
nook-vault-sentinel | Independent Svelte 5 Sentinel Vault application |
nook-web-app | Public site and unified local e2e harness |
nook-web-extension | Simple-only Manifest V3 companion (Nook Pilot: login HUD, credential fill, takeover) |
nook-web-shared | Presentation/browser glue safe to share between vault apps |
Inside nook-web-shared/src/vault-app/lib, browser-owned modules are grouped by
capability (app, auth, content, enrollment, extension, runtime, and
vault). Provider-specific authentication adapters live under auth/google
and auth/icloud; portable provider policy remains in Rust.
Deeper documentation lives in .cortex/:
Development issues are stored in the versioned Nook Workbench instead of this repository's GitHub Issues or source tree. Agent plans, worklogs, and build statistics are not published there.
| Channel | Site | Simple | Sentinel |
|---|---|---|---|
| Production | nokey.sh | simple.nokey.sh | sentinel.nokey.sh |
| Main (dev) | dev.nokey.sh | simple.dev.nokey.sh | sentinel.dev.nokey.sh |
| Pull requests | Cloudflare pr-<number>.<project>.pages.dev branch aliases | matching Simple alias | matching Sentinel alias |
Each PR site and dev.nokey.sh publish a browser-extension ZIP under
/downloads/. Immutable production releases publish the versioned ZIP at
nokey.sh and on the GitHub Release. Production installs go through the Chrome
Web Store; the ZIP remains a verifiable release artifact.
Prerequisites:
The root Taskfile.yml is the repository entrypoint. Compile, test, and
package installs run inside the project container. Infrastructure commands use
infra/Taskfile.yml as their composition root and flatten
domain-owned modules from infra/tasks/ into the public
infra:* command surface; standalone infrastructure shell scripts and orphan
domain Taskfiles are prohibited.
Repository automation has one hard language boundary: do not add Python source,
runtime invocations, packages, or inline programs. Use Bun/TypeScript for
scripts and controllers, Rust for compiled behavior, and Taskfiles for
orchestration. task preflight:source-architecture uses one filesystem
inventory and reads only automation-capable files for runtime references.
Project skill semantics live only in team-owned Markdown under .cortex and
are indexed through the AI dynamic-skill catalog. Harness-specific profiles
must remain outside the tracked repository. Use task loom:cortex-audit to
verify canonical links, catalog coverage, and the absence of tracked harness
skill mirrors.
Deterministic implementations of those semantics are ordinary Bun and
TypeScript packages co-located under the owning skill's scripts/ directory.
They share the pinned .cortex Bun workspace and its hoisted dependency tree.
They are code, not skill-card mirrors. Use task skills:install and
task skills:verify for the executable-skill workspace gate.
task loom:verify additionally applies the repository AST capability and
exact-consumer boundary. The Cortex article application is currently consumed
in-process by Loom. Agents can discover and invoke its static action through
task skills:tools-list and one inline-YAML task skills:run request.
task web:dev
The first run builds a pinned mkcert utility container, writes TLS material
under ~/.nook/https/ (shared across git worktrees), and asks the host OS to
trust that local CA. Leftover checkout-scoped .nook/https/ material is copied
once into the home directory before a new CA is minted.
Open https://localhost:5173 for the landing page, or
https://localhost:5173/app/ for the unified
local test harness. Production builds are bun run build inside
nook-vault-simple and nook-vault-sentinel; they never use a hostname flag
to select a vault type.
All web surfaces consume one audited nook-wasm package compiled once. Each
entrypoint configures its immutable Rust-owned application identity before
loading app modules, so Simple and Sentinel remain separate projects and
origins without recompiling the same Rust library per surface.
setup runs automatically before docker tasks and rebuilds the nook-web:local
image so it reflects current source. Buildx prepares the Rust/WASM and web
dependency branches in parallel, exports generated WASM and coverage through a
commit-scoped host directory, then builds a web-only image. Concurrent builds
cannot consume each other's handoff; Rust target/ and the compiler toolchain
never enter nook-web:local.
Rust compilation can use authenticated SeaweedFS S3 sccache deployed from
infra/ at https://sccache.dev.nokey.sh. Authorized local and
trusted Main builds write nook-sccache; manually dispatched Remote tasks
use a separately authorized read-only identity for that bucket. Branch builds
reuse trusted compiler objects but cannot replace them.
Run task infra:sccache:credential:sync and
task infra:registry:credential:sync once to create mode-0600 credentials in
~/.nook/cache/ (shared across checkouts; never written into the repo). Registry
sync also runs docker login registry.dev.nokey.sh. Local Rust builds require
those S3 key files (task sccache:ensure fails closed without them). Secret-free
hosted jobs set SCCACHE_OPTIONAL=1 and compile without sccache. Trusted Main
receives the read/write bucket identity; explicit Remote tasks receive the
read-only identity. Pull-request, arbitrary-ref, dependency-update, and
AI-authored jobs receive neither. Stable BuildKit secret IDs keep credential
values out of layer cache keys. Override the endpoint with SCCACHE_ENDPOINT.
Runtime containers receive an explicit 1,048,576 open-file limit; override it
with DOCKER_NOFILE_LIMIT.
macOS has no inotify; Docker workloads use the inotify implementation in Docker Desktop's Linux VM. Reapply after Docker Desktop restarts:
docker run --rm --privileged --pid=host registry.dev.nokey.sh/library/busybox:1.37.0 \
sysctl -w \
fs.inotify.max_user_instances=2500 \
fs.inotify.max_user_watches=10485760
On Linux development hosts, raise and persist the same kernel-wide limits:
sudo sysctl -w fs.inotify.max_user_instances=2500
sudo sysctl -w fs.inotify.max_user_watches=10485760
printf '%s\n' \
'fs.inotify.max_user_instances=2500' \
'fs.inotify.max_user_watches=10485760' \
| sudo tee /etc/sysctl.d/99-nook-docker.conf
sudo sysctl --system
To raise macOS file-descriptor ceilings by 10×:
sudo sysctl -w kern.maxfiles=2764800
sudo sysctl -w kern.maxfilesperproc=1382400
sudo launchctl limit maxfiles 1382400 2764800
The launchd limit applies to newly launched processes — reopen affected terminals afterward.
To use GitHub sync, connect a personal access token in the UI. Nook stores the
encrypted event log under nook-log/v1/events/ in a private repository.
Delivery uses one Gizmo context and five Cortex engineering team domains:
Gizmo Prime owns coordination, integration, lifecycle state, and the final integrated PR verdict.
AI owns Cortex, Loom, agent skills, expert routing, self-improvement, and deterministic AI automation.
Development core owns portable Rust, Rust/WASM domain contracts, security logic, and core product specifications.
Security owns security architecture, cryptographic policy, trust boundaries, and security acceptance.
SRE owns CI/CD, runners, containers, k0s, Kubernetes, deployments, and provider operations.
Web development owns browser apps, extension presentation, Svelte/TypeScript interaction behavior, browser evidence, and repository-wide TypeScript/Svelte engineering practices.
The root Cortex graph routes delivery control to Gizmo and implementation to one functional team owner. That owner may request a bounded unit from another implementation team as an expertise provider. Gizmo is never an expertise provider. Each worker loads only its own team graph and the explicit expertise contract. Shared knowledge is loaded only for a named cross-team dependency. It is not an implementation team.
Ordinary implementation agents return verified worker branches to Gizmo. The
upstream integration agent integrates them into the feature branch, and the
Feature Gizmo authorizes Delivery Pipeline to publish it and request the hosted
build:compile task through task remote TASK_NAME=build:compile.
Feature-stage execution is build-only. Full tests, coverage, preflight, e2e,
and complete PR validation belong to the feature pull-request lifecycle. The
Feature Gizmo authorizes PR Lifecycle Agent to apply the validation labels
required for the selected branch and observe the resulting hosted checks.
Ordinary validation does not contact Codex. Local Task mirrors below remain
available for humans. Main-fix PRs use ci:full-e2e to request the
Main-equivalent browser suites.
Project-scoped module experts use stable semantic role names defined by the
Cortex registry. Universal
worker behavior follows the root Cortex contract. The
typed Loom catalog mirrors their roles and bounded read-only context.
Run task loom:module-experts:validate to verify complete production-module
routing, generated WASM binding contracts, the
internal_api_expert boundary, and research exclusions. Gizmo selects and
invokes module experts through the active harness; Loom does not own an expert
journal, replay, or completion-handoff path.
Structural refactoring uses a separate read-only expert registry so overlapping
maintenance scopes do not pretend to own production modules. Run
task loom:structural-experts:validate to verify the exact code, Cortex,
and synthesis role contracts. Gizmo invokes these roles through the active
harness. Every role remains nondelegating and read-only. See the
structural refactoring registry
and workflow.
task loom:cortex-session-clean # assert temporary agent memory is removed
task loom:module-experts:validate # named read-only expert and production-module routing audit
task loom:structural-experts:validate # exact structural role and bounded-scope audit
task remote TASK_NAME=rust:ci # BuildKit-native Rust lane on ARC when enabled
task remote TASK_NAME=preflight # repository invariant checks on exact pushed HEAD
task remote TASK_NAME=web:build # direct-Pod web build
task remote TASK_NAME=web:e2e # direct-Pod browser proof
task remote TASK_NAME=extension:e2e # direct-Pod extension browser proof
task pr:validate PR=410 # complete exact-head validation without Codex review
task pr:validate PR=410 FULL_E2E=1 # final Main-fix gate
task check # format, lint, tests, coverage floor, builds (optional local / CI mirror)
task preflight # fast Rust checks for whole-repository invariants
task build # Rust, WASM, web, and extension production build
task web:dev # trusted-HTTPS local Vite development server
task web:test # web unit tests
task web:test:e2e:pr # fast Playwright subset (IndexedDB / local provider)
task web:test:e2e:isolation # Simple/Sentinel project and origin boundary suite
task web:test:e2e # full local-provider Playwright suite (no PAT)
task web:test:e2e:sync-live # live GitHub sync e2e (requires NOOK_GITHUB_PAT)
task extension:build # browser extension package
task extension:check:fast # host-cached extension format/unit/manifest/security gate
task extension:build:localhost # local-only identity targeting trusted HTTPS localhost
task extension:install:hosted PR=410 # verify and install an isolated hosted PR build
task extension:smoke:hosted CHANNEL=dev # disposable Chromium hosted extension + Simple Vault smoke
task extension:setup:brave CHANNEL=dev # Brave PIN bootstrap: install, create vault, approve, leave open
task extension:run:chrome CHANNEL=dev # Chrome for Testing auto-loads; branded Chrome opens one-time setup
task extension:run:brave CHANNEL=prod # launch a hosted build in an isolated Brave profile (no vault setup)
task ci:pr # optional local mirror of the non-browser PR gate (daemon BuildKit; never shared nook-pr)
task ci:pr:e2e # explicit full web + extension e2e validation (optional)
task pr:preflight PR=410 # JSON audit: base, policy, exact-head runs/deployments, feedback
task pr:review PR=410 # optional circuit-guarded exact-head Codex review request
task pr:review:stabilize PR=410 # one bounded feedback snapshot after validation dispatch
task docker:coverage:export # coverage-only CI fallback (no app image export)
task sccache:stats # shared SeaweedFS S3 compiler-cache object presence
task infra:deploy # deploy SeaweedFS/registry plus k0s, Kata, and ARC
task infra:ovh:server:deploy INFRA_OVH_SERVER=nook-rise-s-2 # install/reconcile a declared OVH worker and join k0s/ARC
task infra:ssh:home:configure # install and prove pinned browserless LAN SSH for the home worker
task infra:ssh:home:status # verify the home worker remains reachable without interactive authentication
task infra:arc:deploy # deploy ARC plus one persistent BuildKit shard per build node
task infra:arc:activate # route opted-in trusted Rust and remote jobs to ARC
task infra:arc:fallback # route opted-in Rust and remote jobs to GitHub-hosted capacity
task infra:kubernetes-cache:prove # prove production-derived Zot and BuildKit behavior on ephemeral k3d
task infra:kubernetes:console:install # install kubectl, Helm, k9s, and SSH-user access
task infra:kubernetes:tools:status # verify the remote operator console
task infra:k0s:status # inspect the remote cluster and workloads
task infra:k0s:diagnose # bounded k0s, CNI, firewall, and control-plane evidence
task infra:k0s:network:refresh # recreate egress-capable Pods after a CNI migration
task infra:kata:verify # prove a Pod is using the Kata guest kernel
task infra:kata:diagnose # bounded Kata installer and runtime evidence
task infra:services:diagnose # bounded Docker and Compose network evidence
task infra:services:repair-network # recover Docker 26 chains without daemon restart
task infra:status # inspect the remote infrastructure stack
task infra:sccache:check # remote SeaweedFS S3 anonymous-deny + signed access
Expensive remote browser/full-suite dispatches and the initial
task pr:validate request refresh the target base first and stop immediately
when the branch is behind. Merge the reported origin/<base> into the delivery
branch before spending hosted validation.
Labeled PR validation and merged-head verification run the shared Rust
ecosystem gates through pr.yml and main.yml. Each lifecycle therefore
shows product and ecosystem checks on one Actions run.
task docker:ecosystem:* runs dependency policy (per-workspace Taskfile
checks in the cache-only rust-ecosystem-dependency-policy BuildKit target), RustSec,
Proptest/Insta/Loom, cargo-fuzz, and Dylint from sibling Dockerfiles under
nook-app/nook-platform/docker/rust/ as separate images off rust-base
(rust-ecosystem-policy-tools, rust-ecosystem-nightly) so the product base
stays lean. Kani runs through its Dockerized Task target. Also covered:
generated and snapshot tests (Proptest and Insta),
bounded concurrency exploration (Loom), parser fuzzing (cargo-fuzz), model
checking (Kani), and repository-selected Rust lints (Dylint). Fast
deterministic tests remain part of ordinary Rust testing. Fuzz, Loom, Kani, and
compiler-coupled Dylint checks have bounded hosted jobs. Main also covers
minds-only and mixed pushes while skipping product jobs for minds-only changes.
Schedule, manual, and labeled minds-only PR entry points stay in thin
rust-ecosystem.yml. The selection and configuration policy lives in
.cortex/teams/sre/workflows/quality.md.
See infra/k0s/README.md for the failed Main-repair
inspection and recovery workflow.
PR browser suites run directly in the validation runner; no PR-specific browser image is published.
Live sync e2e reads NOOK_GITHUB_PAT from the environment or
nook-app/nook-web/nook-web-app/.env.test.local; see
.env.test.example next to that file.
Architecture changes belong in the lowest appropriate layer: shared
dependency-light application primitives in nook-app-common, key access in
nook-auth2, provider-neutral causal replication mechanics in
nook-replication, signed vault history and projection in nook-event-log,
vault application services in nook-core, browser I/O in nook-wasm, and UI
in nook-web-*. When package boundaries, sync model, or public Task commands
change, update this README in the same change (see
.cortex/AGENTS.md).
Docker builds use cargo-chef
and independent linux/amd64 Rust, web dependency, and browser lineages.
Trusted PR validation uses one ordinary ARC job Pod on nook-k0s-container.
All steps use one checkout and the persistent rootless BuildKit shard on that
Pod's node. Rust and web solves run in BuildKit; Playwright runs directly in the
job Pod. The hook supplies a Docker CLI only: no daemon, runtime socket, DinD,
host path, or privileged job container. The runner uses a pinned infrastructure
Debian browser image, not an image published for each Nook PR.
The one-job phases are ci:pr:verification, ci:pr:tests, then the joined
ci:pr:post-tests barrier. The test phase keeps Docker-side coverage
generation and per-package floor enforcement in BuildKit; the post-test
barrier runs heavy checks and browser-artifact preparation concurrently before
optional browser suites.
Verification includes formatting, Loom/tooling checks, Clippy, TypeScript
checks/lint and product builds before expensive test compilation. Independent
work runs concurrently within each phase. Preview publication stays in the
same job; PR coverage artifacts and comments are no longer transported or
reported.
The phase definitions live in nook-app/ci/pr.yml and
nook-app/ci/pr.docker-bake.hcl; coverage/preview use composite actions,
not reusable workflows that allocate additional runners.
PRs do not import/export registry layer caches or publish intermediate Nook images. Local outputs contain browser/deployment files only; coverage remains inside the Docker/BuildKit solve and is enforced there. Later PRs can land on another node: warm cross-run locality is not guaranteed. Main, release and explicit remote workflows retain their existing portable Zot cache/image contracts. The node-local Service prevents cross-node BuildKit traffic, and sccache remains the shared compiler-object cache.
task infra:arc:deploy temporarily quarantines every declared build node from
new ARC scheduling while it converges host prerequisites. It persists
kernel.keys.maxkeys=20000 and kernel.keys.maxbytes=2000000 in
/etc/sysctl.d/91-nook-buildkit-keyring.conf, applies them at runtime, and
verifies every host before reactivating any node. Operators need passwordless
sudo for sysctl, install, and the existing k0s administration commands.
Fork and Dependabot PRs use secret-free GitHub-hosted containers and a hosted builder. Trusted PRs keep the full sccache credential tuple, telemetry and zero-hit health gate. No cluster infrastructure or registry ACLs are changed by the workflow itself.
task infra:bake-cache:prove-pr is the Docker-backed PR simulator proof.
It creates a disposable builder and runs real cold/warm verification, test and
heavy solves without Zot, checks their outputs and verifies failure barriers.
Logs and BuildKit metadata remain in the printed temporary output directory.
The existing task infra:bake-cache:prove runs this local-cache proof before
its registry-portability scenarios. No custom cache-validity model is used.
Before enabling the new PR path, publish the source-free runner through the
trusted remote ARC workflow with task remote TASK_NAME=ci:pr:runner:publish.
The workflow uses package-write only for this publication; PR jobs receive
package-read and authenticate the job container with their scoped token. Then set the repository variable
NOOK_PR_RUNNER_IMAGE to its immutable ghcr.io/...@sha256:... digest.
This image uses the same Debian Trixie ABI as the exported preflight reporter,
with system Chromium, ffmpeg, Xvfb, Bun, Node and Task, but no product source.
It is rebuilt only when the runtime tooling changes.
Deploy the updated ARC container hook and
BuildKit ingress policy. Job containers need the injected Docker client and
node-local BuildKit access. Required-check settings should reference
PR validation / Verify and preview; obsolete split-job checks must be
removed by an administrator. Neither deployment nor settings changes are
performed automatically by this feature.
task infra:kubernetes-cache:prove is the local portable Kubernetes integration
proof. It creates three k3d agents and patches the production Zot, rootless
BuildKit, and NetworkPolicy resources. Docker creates only the k3d
infrastructure containers.
Kubernetes workloads receive no runtime socket, service-account token, host
path, or privileged context. The proof covers cache persistence and
cross-shard portability. Clients run on their selected shard's node through the
production node-local Service. The proof does
not replace production evidence for k0s, node-local Service routing, WireGuard,
Kata, ARC lifecycle, capacity, or performance. CI checks the static proof
contracts but does not run k3d.
Workspace source is copied into the slim nook-web:local image (sealed image;
no runtime bind mount except task web:dev). Explicit task rust:* and
task wasm:* commands load a separate source-sealed Rust image on demand.
Rust compilation has a second cache boundary below Docker layers: pinned
sccache clients use authenticated SeaweedFS S3 to reuse compatible
source-sensitive compiler outputs whenever credentials are available.
Same-repository Main, PR, Rust ecosystem, and Remote jobs mount those
credentials; fork/release/secret-free builds bypass sccache. SeaweedFS does not
cache Cargo downloads or Docker layers.
PR CI enforces package coverage floors inside the Docker/BuildKit solve and
does not upload or comment on a redundant coverage report. The old exact-input
artifact-promotion and Main-baseline comparison workflows are removed:
Docker/BuildKit owns reuse of unchanged verification layers.
No new performance budget is claimed until cold/warm measurements are run.
After changing Rust dependencies, commit the updated lockfile:
cd nook-app/nook-platform && cargo generate-lockfile
git add nook-app/nook-platform/Cargo.lock
Nook is available under the MIT License.