Packaged Blackcap deployment
Commercial Blackcap packages can be delivered as customer-specific archives without requiring access to the Blackcap Git repository. The package contains a compiled Blackcap runtime, an installer, safe package metadata, and a signed Microwave Pie License Key bootstrap.
Package privacy
Keep the original deployment ZIP private. It contains the signed License Key assigned to that package. Possession of the package is effectively possession of that credential; normal License binding, duplicate-use detection, scope, revocation/replacement, and Trial expiration remain the enforcement controls.
The package does not contain Microwave Pie's private licensing signing key.
Installation
For the initial Linux AMD64/GCP target, the supported package guide assumes a Debian/Ubuntu-style host. Install the bootstrap tools before using the package:
sudo apt-get update
sudo apt-get install -y curl unzip
The Tracker online Installation Guide can generate a fresh package-specific VM/server curl command using the existing Package authorization flow. That command carries a short-lived Package-only credential rather than a Tracker administrative token, downloads the exact package filename used by the extraction step, and fails visibly on HTTP errors. The downloaded archive still remains a credential-bearing private artifact.
Then:
- Download or copy the package to the intended Linux host.
- Extract the exact ZIP filename shown by the Package Installation Guide into a private working directory.
- Run
sudo bash install.sh. - The installer verifies the compiled payload SHA-256, installs the versioned runtime under
/opt/blackcap/releases/, and keeps persistent Blackcap state outside that release directory. The package manifest also carries a separate Microwave Pie distribution signature for provenance/audit; MPL1 remains the local licensing trust boundary. - The installer places the License Key bootstrap at a protected
0600working path and starts theblackcapsystemd service. - On startup, Blackcap validates the MPL1 signature and application claim, verifies that the bootstrap package/download metadata matches the installed package metadata, and imports the credential through the normal protected licensing service.
- Blackcap reads the persisted license back and removes the protected bootstrap working copy only after successful import.
- Blackcap then uses the normal Tracker activation/binding/heartbeat workflow. If Tracker is unavailable, existing offline license behavior applies.
The original downloaded ZIP is not modified or deleted by Blackcap. Store or delete it according to your own secure software-delivery policy.
Existing license protection
A package bootstrap never silently replaces a different valid installed License Key. If a valid license is already installed, the package bootstrap remains unused and normal License Details/remediation is required for an intentional replacement.
Reprocessing the same already-imported package is idempotent.
Trial packages
For a packaged Trial, the Tracker creates the final signed Trial credential only when the actual package file download starts. Opening the emailed Tracker link, viewing the preparation page, or waiting for a reusable release build does not start the Trial. The signed offline fallback therefore starts with package delivery rather than when the administrator originally created the Package record.
Downloading the package again reuses the same signed Trial credential. Reinstalling or re-downloading cannot restart or extend the Trial. The normal online-first-registration versus offline-first fallback-lock rules still apply after installation.
Upgrades and persistence
A package installation separates the versioned runtime from persistent state:
- versioned compiled runtime:
/opt/blackcap/releases/<release reference>/; - active runtime link:
/opt/blackcap/current; - configuration:
/etc/blackcap/; - database, installation identity, License repository, and distribution metadata:
/var/lib/blackcap/; - mutable application working state:
/var/lib/blackcap/runtime/, including recipe/emoji/noun caches, display previews, AI-generated image candidates, and regression/browser artifacts.
The compiled release under /opt/blackcap/releases/ is read-only application content. Packaged path resolution redirects known generated relative paths to /var/lib/blackcap/runtime/ while leaving bundled code, documentation, migrations, regression fixtures, and Chrome Extension source under the immutable release. Built-in noun/emoji seed assets are copied into the writable runtime only when missing, so upgrades do not overwrite customer-generated cache content. Installing a newer package changes the active runtime link while preserving persistent state. A normal software update does not require a new License Key.
Package metadata includes the authoritative full Git commit SHA. The human Blackcap version is informational.
Package/instance reporting
Blackcap reports only safe distribution metadata through the existing Tracker heartbeat: Package reference, Package Download reference, Release reference, full Git commit, informational version, platform, and manifest digest. The License Key is never included in this metadata.
The Tracker uses a validated licensed heartbeat to associate the downloaded package with the actual Blackcap installation and mark it Installed.
Compiled web-server validation
The compiled Linux AMD64 release explicitly includes the Gunicorn package because Gunicorn resolves some components, including its logger and threaded worker class, from string URIs at runtime. The release build runs the compiled runtime's runtime-check command before publication; if those dynamically selected Gunicorn modules cannot be loaded, the release build fails instead of allowing a package that would only fail after installation.
Initial Linux network setup
The first Linux AMD64 installer binds Gunicorn to 127.0.0.1:8080 and preserves Blackcap's normal external-HTTPS enforcement. For initial setup, use an SSH tunnel or another local-only administrative path rather than opening port 8080 to the internet. Before normal internet-facing operation, place Blackcap behind the supported HTTPS reverse proxy/TLS configuration and restrict host/firewall access as appropriate. See Reverse proxy and TLS.
Troubleshooting
If installation succeeds but Tracker does not show the Package as Installed, verify that:
- Blackcap has successfully imported the package License Key;
- the License is Active or has otherwise successfully validated online;
- instance reporting is enabled and can reach the Tracker;
/var/lib/blackcap/blackcap-distribution.jsonexists and contains the Package/Download/Release metadata installed with the package;- the package was not superseded by a different valid License Key before the heartbeat.
Use Blackcap License Details and its Refresh License Details action to trigger the normal reporting path. Do not paste the full License Key into logs or support diagnostics.
Guided Linux AMD64 installer
Tracker-generated Linux AMD64 Packages now include a guided install.sh and INSTALLATION-GUIDE.md. On Google Compute Engine the installer detects the project ID, VM name, zone, and service account from the metadata server. It asks for the Cloud SQL private/public network choice, Cloud SQL instance name, a single database/user name, and a hidden password. It configures the Cloud SQL Auth Proxy, PostgreSQL environment, Blackcap INI, systemd dependencies, migrations, and application services automatically.
Project-level operations remain deliberate prerequisites rather than permissions the Package grants to itself: enable the Cloud SQL Admin API, grant roles/cloudsql.client to the VM service account, use a Cloud SQL-capable VM OAuth scope, create the Cloud SQL SQL user, and ensure private-IP VPC connectivity when applicable. The installer checks these prerequisites and prints recovery commands without broadening IAM.
Compiled Python migrations
Python migration implementations are compiled under inky_admin.packaged_migrations. The standalone distribution preserves the existing filename-based migration registry with one-line stubs under database/migrations/*.py that import each compiled apply function. This keeps migrations dynamically discoverable without shipping their implementation source.
The PostgreSQL current-schema fast path checks information_schema.tables before touching app_meta, schema_migrations, or other application tables. A completely empty or partially initialized PostgreSQL database therefore returns "not current" without triggering an UndefinedTable error that would poison the transaction when statement savepoints are disabled.
Compiled runtime validation
Before a compiled base release is published, the build validates the packaged storage contract, builds a fresh SQLite reference schema through the compiled dispatcher, runs an isolated SQLite migration, creates and renders a real editable recipe through the compiled renderer, and then performs a real Gunicorn/Flask HTTP startup smoke test with the compiled binary. The HTTP smoke test requires an HTTP response from a loaded WSGI worker so dynamically imported dependencies omitted by Nuitka cannot pass merely because the Gunicorn master bound the port.
Compiled packages do not assume a sibling Python interpreter exists. Package-critical helper work that source/Pi deployments normally invoke as Python scripts is dispatched back through blackcap-runtime.bin (currently recipe rendering and menu refresh), and database parity creates its isolated SQLite reference schema through the same compiled runtime. The release also includes the Blackcap-Pi-Extension files needed by regression/browser checks and fails the build if required extension assets are absent.
Packaged Flask session secret
Packaged installations must provide a stable INKY_ADMIN_SECRET through the root-managed /etc/blackcap/blackcap.env file. The package installer generates this value automatically and keeps it across normal reinstall/retry flows. The packaged systemd unit enables BLACKCAP_REQUIRE_STABLE_SESSION_SECRET=1, so Blackcap fails closed instead of starting multiple Gunicorn workers with different process-local session keys. The secret value must never be logged or placed in customer-visible package metadata.