Browse documentation

🧭 Start Here

Blackcap Overview ✨ Blackcap Feature Catalog 🧱 Technology, Administration, and Reliability Installation First Run

🚀 Deploy Blackcap

Platform Stacks and Raspberry Pi Hardware Raspberry Pi Deployment Raspberry Pi Client Services GCP Deployment Packaged Blackcap deployment Application Updates Blackcap Release Notes Environment Variables and Secrets Reverse Proxy and TLS Background Jobs and Schedules

🛠️ Administer Blackcap

Organizations Users, Permissions, and Authentication Configuration Workspace Backups and Restore Database Administration Regression Testing Performance and Job Status Audit, Access Activity, and Logging GeoIP and Access Location Data Retention and Purge Support Chat Administration Support Requests API Tester and Postman Instance Reporting Microwave Pie licensing for Blackcap Microwave Pie licensing for Blackcap

🍽️ Use Recipes

Recipes and the Recipe Library Recipe Import and Discovery Recipe Editing and Cache Artifacts Recipe Sharing Social Recipe Import AI Recipe Image Generation

📅 Plan Meals

Meal Planner

🛒 Use Shopping Lists

Shopping Lists and Shop a List External and Household Shopping 🧩 Chrome Extension Shop With

🧺 Manage Kitchen Inventory

🧺 Kitchen Inventory

🖥️ Use Displays

Displays and Connections Assigning and Scheduling Display Content Remote Pi Client E-Ink Rendering Menu Refresh and Rendering Noun Project Footer Images

🧑‍🍳 Cook with Let’s Cook

🧑‍🍳 Let’s Cook 🧑‍🍳 Let’s Cook Controls and Timers

🤖 Use and Administer AI

🤖 AI in Blackcap 🤖 AI Providers and Connections 🤖 AI Seeds and Usage Support Chat

🧩 Use the Chrome Extension

🧩 Blackcap Chrome Extension 🧩 Chrome Extension Recipe Capture 🧩 Chrome Extension Shop With 🧩 Chrome Extension Release and Privacy

🎮 Play Games

🎮 Games and Trivia

🔌 Integrations

Email Integration Cloud Storage Integrations Voice Assistants Shop With Integrations Authentication Providers

⚙️ Develop Blackcap

Application Architecture Database Service and Data Access SQLite and PostgreSQL Database Migrations Background Job Architecture Testing API Architecture Security and Organization Scoping UI, Icons, and Documentation Assets Blackcap-Safe Emoji Support Chat Architecture Extending Support Chat Support Chat Model Benchmark Documentation Standards Terminology

⚠️ Troubleshoot Blackcap

⚠️ Troubleshooting Licensing Troubleshooting Deployment Troubleshooting Display Troubleshooting Recipe Import Troubleshooting 🤖 AI Troubleshooting Backup Troubleshooting Database Troubleshooting Diagnostic Organization Clones Support Chat

Instance Reporting

Audience: System Admin, Deployment Administrator, Support Related: Audit And Logging · Environment And Secrets

Privacy-conscious instance reporting provides deployment identity, lifecycle, version, and safe operational metadata for configured reporting workflows. It is separate from end-user activity and must avoid transmitting recipes, credentials, private content, or unrestricted logs.

Runtime branding and host-aware behavior should use the deployment’s configured public identity rather than hard-coded production values.

Blackcap automatically registers each installation with the Microwave Pie software delivery and instance management service and sends a privacy-conscious heartbeat approximately every six hours. Reporting is part of the normal Flask/Gunicorn application lifecycle: starting inky_admin.service starts reporting, and stopping that service stops it.

Runtime architecture

  • inky_admin/services/instance_tracker_service.py owns deployment/environment detection, payload construction, registration, heartbeat timing, retry/backoff, revocation, and the application-owned reporting loop.
  • inky_admin/services/instance_tracker_db_service.py provides durable identity/state storage and aggregate database health through Blackcap's centralized provider-aware database services.
  • inky_admin/repositories/instance_tracker_repository.py is the only repository that reads or writes the private internal state row.
  • inky_admin/inky_admin_app.py schedules the reporting loop after normal application database initialization.
  • A process-lifetime file lock elects one local Gunicorn worker. Other workers exit their startup timer immediately.
  • A short database lease prevents duplicate traffic if multiple Blackcap application hosts point at the same database.
  • There is no separate instance-reporting systemd service, timer, cron entry, Admin setting, or user-facing disable switch.

Configuration

BLACKCAP_ENVIRONMENT="production"

Supported normalized values are production, staging, development, test, demo, and unknown. Blank values default to Production. Instance registration and heartbeat traffic always uses the built-in management-service endpoint https://tracking.microwavepie.com; the URL is not configurable through Blackcap settings or environment variables.

Durable identity and state

The stable installation identity, permanent token, retry state, heartbeat timestamps, boot marker, and current lifecycle state are stored in Blackcap's application database. SQLite and PostgreSQL use the same provider-aware repository path.

Permanent revocation also writes ${BLACKCAP_RUNTIME_DATA_DIR}/instance-tracker/revoked.json. This credential-free tombstone is created atomically with 0600 permissions inside a 0700 directory. Its presence always overrides the database, so restoring an older database or switching providers cannot reactivate a known revoked installation through supported application paths.

The backing internal_service_state table is application-internal. It is intentionally:

  • absent from the Database Admin resource registry;
  • absent from SQL Console schema/autocomplete/export metadata;
  • blocked from direct SQL Console and CSV-export queries;
  • omitted from detailed database parity schema output; and
  • not exposed through an Admin route or setting.

Because identity now follows the application database, restoring or replacing the database also restores or replaces the instance-management identity. A database migration between SQLite and PostgreSQL should therefore include this internal row when the installation is intended to keep the same instance-management identity.

Data sent

Blackcap sends its application name/version/build, normalized environment, deployment type and detection source, Python/OS/architecture, SQLite or PostgreSQL provider, Blackcap schema version when available, aggregate user/recipe/organization/display counts, sanitized database availability, and safe license-reconciliation metadata when licensed. On Google Compute Engine, the heartbeat also includes a fixed metadata.hosting allowlist containing provider (gcp), project ID, instance name/id, region, zone, and machine type. Regression-test organizations, diagnostic-clone organizations, and their organization-scoped users, recipes, and displays are excluded from these counts. Reports include the metadata marker aggregateCountsPolicy=exclude_regression_and_diagnostic_organizations_v1 so newly filtered snapshots can be distinguished from older heartbeat history. The full Microwave Pie License Key is never sent in a routine heartbeat. The Google metadata enrichment uses only the same fixed, credential-free paths used by the System page; service-account tokens, credentials, and unrestricted metadata are never requested or transmitted. Blackcap never sends customer content or Blackcap application credentials.

Scheduling and duplicate protection

One elected Gunicorn worker performs a due check shortly after application startup and then every 15 minutes. Database state enforces the normal six-hour heartbeat interval and management-service-provided interval bounds. A new system boot allows one early heartbeat. Every accepted Microwave Pie management-service heartbeat now includes the Microwave Pie management service's normalized Blackcap update decision, so Blackcap consumes current update availability whenever it reports normal application status. There is no separate time-based suppression window and the 15-minute loop does not issue an additional update-candidate request when a heartbeat itself is not due.

Network and management-service failures use persisted bounded exponential backoff with jitter: approximately 15 minutes, 30 minutes, 1 hour, 2 hours, 4 hours, then at most 6 hours. Reporting failures never fail an HTTP request, display refresh, scheduled job, or Blackcap background-job record.

An explicit instance_paused response changes the entire Blackcap installation to a locally enforced paused state. Admin, Mobile, API Tester, API-token requests, display/receiver APIs, voice commands, scheduled operations, and Blackcap background workers are blocked or skipped. The health endpoint remains available and reports the lifecycle state. While paused, the login page and any blocked browser landing page perform a short authenticated GET /api/v1/instances/status check; when the management service reports active, Blackcap clears the temporary pause and normal activity resumes. If the management service is unavailable, the installation remains paused. The paused and revoked landing pages direct users to blackcap@microwavepie.com when they believe the status is incorrect. Standalone Blackcap scripts never call the management service: they read the durable local lifecycle state and exit successfully before performing work when the installation is paused or revoked.

An explicit instance_revoked response permanently locks the entire installation, writes the independent revocation tombstone, stops management-service traffic, and prevents Blackcap from generating a replacement identity. Login never attempts to clear a revoked state.

Lifecycle changes are normally learned during the next due heartbeat. A System Admin may force immediate detection while the installation is still active through API Tester → System → Trigger Instance Report.

Deployment detection order

  1. Raspberry Pi model information.
  2. Docker marker or container cgroup evidence.
  3. Google Compute Engine metadata using the required header and sub-second timeout.
  4. Google DMI values.
  5. Generic Linux fallback.
  6. Unknown platform fallback.

Operations and troubleshooting

Reporting is supervised by the existing application service:

sudo systemctl status inky_admin.service --no-pager -l
sudo journalctl -u inky_admin.service -n 200 --no-pager | grep -i "instance heartbeat\|instance registration\|instance reporting"
sudo systemctl restart inky_admin.service

A System Admin can also open API Tester → System → Trigger Instance Report. The action accepts no request data: Blackcap builds the same production registration/heartbeat payload locally, forces one attempt, and returns only masked identity state plus sanitized connectivity, deployment-detection, database-provider, retry, and revocation diagnostics. The internal trigger is CSRF-protected, requires the API Tester mutating confirmation, and is not exported to Postman.

Instance reporting now carries software-update discovery as part of the same authenticated heartbeat response. Trigger Instance Report therefore forces the normal registration/heartbeat path and, when the Microwave Pie management service accepts that heartbeat, Blackcap also consumes the Microwave Pie management service's current approved update decision. API Tester Blackcap Update Status remains a passive view of the persisted result, while Check for Latest Blackcap Update remains an explicit live refresh action.

The scheduled-operations installer removes obsolete blackcap_instance_tracker.service and blackcap_instance_tracker.timer units from earlier builds.

Lifecycle enforcement

  • Local active plus management-service/network outage: Blackcap continues operating.
  • Local paused plus management-service/network outage: Blackcap remains locked.
  • Local revoked: Blackcap remains permanently locked.
  • /health remains HTTP 200 and includes lifecycle_status plus activity_allowed.
  • Browser requests receive a branded pause/revocation page; API-like requests receive instance_paused or instance_revoked.
  • Cron operations write a successful skipped status and exit 0 while locked. Long-running watchers poll local lifecycle state and perform no display/client work while locked.

System-page hosting metadata

The System page can show safe host metadata independently of instance registration. On Google Cloud, Blackcap reads only fixed allowlisted paths from the link-local Compute Engine metadata service with the required Metadata-Flavor: Google header and a short timeout. Available fields include provider, project id, instance name/id, zone, region derived from the zone, and machine type. Results are cached because this metadata changes infrequently.

The region id and zone are authoritative cloud metadata. Any human-readable regional label is a local, secondary approximation (for example a broad US region) and must not be described as a particular data-center building or city. Raspberry Pi/local/container deployments report only safe information Blackcap can actually establish, such as host kind, hostname, platform/architecture, and configured timezone. Missing cloud metadata degrades to the normal local/generic host description and never breaks the System page.

Cloud metadata handling does not accept caller-provided URLs and does not expose service-account credentials, tokens, or secret metadata. AWS/Azure-specific metadata probing is intentionally deferred until Blackcap has a concrete need for those providers rather than turning System information into a cloud inventory subsystem.

Build version reporting

Package-managed instances report both forms of build provenance:

  • Git Version — the numeric package-build commit count used for normal user-facing version display;
  • full Git SHA — technical internal provenance retained for Microwave Pie package identity, ancestry, diagnostics, and exact health verification.

Blackcap does not calculate Git Version from an installed .git directory. Source and compiled packages install the number explicitly, so reporting remains exact after archive installation or release-directory moves. The numeric Git Version is display metadata and is never used to decide whether one Git commit is an ancestor of another.

On this page