Skip to content

Publishing Keryx

This is the operational runbook for the first public Keryx release, routine updates, urgent fixes, store review, phased rollout, and product end of life. Keryx is distributed only as SafeCall's first-party notification companion for SafeCall administrators; it is not an independently marketed app. The Keryx adoption strategy defines that product model. Strategic launch gates and unresolved gaps live in the Keryx go-to-market roadmap.

Do not use this runbook as proof that the app is store-ready. Android release signing is closed (#109); iOS distribution signing and the recorded pipeline IPA are closed (#110, #111). First Internal TestFlight and Play Internal installs of 1.0.0+3 are recorded (OA-124-testflight, OA-124-play-internal, 10 September 2026). How-to: internal-testflight.md, ntfy-auth-and-play-internal.md. Soak, Closed testing, production delivery proof, public policy URLs, and store submission still require later P4/P5 evidence. Do not close #124.

Release principles

  1. A successful Flutter build is not a release decision.
  2. Never upload a build produced from an unreviewed or dirty working tree.
  3. Never commit signing keys, certificates, passwords, API keys, App Store Connect keys, Google service credentials, or production ntfy credentials.
  4. The exact binary tested in a store test track is the binary promoted to production.
  5. Every release has an owner, approver, immutable version/build number, source tag, checksums, test evidence, forms snapshot, and rollout record.
  6. Store rollback generally means halting a rollout and submitting a newer fixed build. Do not promise an instant downgrade to an older binary.
  7. Privacy, Data Safety, foreground-service, encryption, and reviewer-access answers must be regenerated from the release candidate and must match the public policies.
  8. Keryx is not described as a guaranteed emergency channel. Use only the approved supplemental / limitation language in docs/gtm/keryx/safety-claims.md.
  9. Store copy, screenshots, reviewer instructions, and client communications must present Keryx as an included SafeCall administrator companion, never as a standalone notification service or consumer acquisition product.
  10. The ordinary administrator journey starts with friendly alert categories and a SafeCall-generated QR code. It must not require manual ntfy server, topic, or subscription configuration.

Release Identity

  • Public store name: Keryx for SafeCall
  • In-app product name: Keryx for SafeCall
  • iOS/Android launcher label: Keryx
  • Legal publisher, seller, and intended Apple/Google account owner: sourcectl
  • Copyright: Copyright © 2026 sourcectl
  • Android application ID: com.sourcectl.keryx
  • iOS bundle ID: com.sourcectl.keryxapp
  • Project path: keryx/
  • Version source: keryx/pubspec.yaml

Roadmap P0-01 approves this identity. sourcectl publishes under the Wantok product umbrella; SafeCall is the contracted platform and Keryx for SafeCall is its administrator companion. BleuVista remains a separate market-facing portfolio/channel, AlertHub is its SafeCall-powered emergency-alerting solution and does not own Keryx, and NavBeacon remains separate.

Only the identifiers are already consistent in the iOS and Android projects (Android com.sourcectl.keryx, iOS com.sourcectl.keryxapp). The source still uses lowercase keryx launcher/bundle names and a SafeCall Flutter title, and the external store accounts, roles, and registered details have not been verified. P2 must propagate the approved naming and P3 must verify account ownership and release metadata before final listings are created. Once an app record is published, changing identity can be costly or impossible.

macOS, Windows, Linux, and web Flutter scaffold directories are not release targets.

Initial market and store classification

Roadmap P0-02 approves:

  • availability in the Czech Republic only on Apple App Store and Google Play;
  • English as the primary/default store language and a complete Czech localization across app, SafeCall provisioning, listings, screenshots, release notes, relevant permission/help copy, and install/support material; see Localization policy (P2-05);
  • Business as the Apple primary category and Google Play app category;
  • SafeCall administrators aged 18 or older as the target audience, with no Apple Kids category, Google Play Families participation, or child targeting;
  • an expected Apple 4+ and Google Play/IARC Everyone content-rating result;
  • no health functionality, no Health & Fitness or Medical category, and a “not a regulated medical device” answer;
  • sourcectl as an EU trader, with Thomas Minitsios owning regulatory and Digital Services Act review.

The content-rating values are expected questionnaire outcomes, not answers to force. Complete the current Apple age-rating questionnaire and Google Play content-rating questionnaire from the final candidate. If either produces a higher rating, return to P0-02. Do not change categories or health/medical answers without revisiting safety claims (P1-10) and P0-02.

For Czech EU distribution, Apple requires verified trader address, phone, and email details on the product page. The Google organization account requires verified identity/address data and public developer phone/email, plus app support contacts. P3-06 stores and verifies the actual values in controlled account records; this document does not claim those external checks are complete.

The classification is approved, but the product is not ready for it: Keryx is currently English-only, SafeCall's Keryx provisioning copy lacks complete reviewed Czech coverage, the bilingual content packet does not exist, and public organization/support details are not verified.

Commercial and reviewer narrative

P0-03 approves this listing lead:

Keryx for SafeCall is a free mobile companion for administrators of a separately contracted SafeCall physical/building deployment. Downloading Keryx does not buy or provide SafeCall. A SafeCall-generated QR configures connectivity and selected alert categories for that deployment; it is not a payment, subscription, license, or paid digital-content unlock.

The approved English/Czech listing packet is docs/gtm/keryx/store-listing-copy.md (P2-02). It puts the dependency before feature copy and states that Keryx has no user account, checkout, subscription, paid Keryx SKU, external purchase link, or in-app purchase. Paste into store consoles only after peer review and per #125.

Use this fact block in Apple and Google review notes (canonical EN/CS templates in the listing packet):

text
App: Keryx for SafeCall
Publisher: sourcectl
Price: Free
Category: Business
Audience: SafeCall administrators aged 18+

Commercial model:
- Keryx accompanies a separately contracted SafeCall physical/building
  deployment.
- Downloading Keryx does not buy or provide SafeCall.
- Keryx has no account, checkout, subscription, paid SKU, in-app purchase, or
  external purchase call to action.

QR clarification:
- The SafeCall-generated QR carries notification connectivity settings and the
  administrator's selected alert categories for that deployment.
- Scanning it does not purchase, subscribe to, license, or unlock paid digital
  content.

How to review:
1. Open the supplied isolated SafeCall-style review environment.
2. Select safe sample alert categories and generate the Keryx QR.
3. Install Keryx, grant required permissions, and scan the QR.
4. Send a safe test notification and verify Active/Archive behavior.

Review access:
- Durable review URL / QR: [controlled release record]
- Monitored contact and phone: [controlled release record]

Do not use client data, production QR payloads, or manual ntfy/topic setup in review. The review environment and QR must remain available for the complete review window.

Clients may assign or install the same public store apps (com.sourcectl.keryxapp on Apple Business Manager; com.sourcectl.keryx on managed Google Play) through Apple Business Manager/standard MDM or managed Google Play. This is an installation channel only. Launch does not support managed app configuration, MDM-injected credentials, deep-link provisioning, zero-touch setup, custom/private binaries, or silent configuration. Administrators still grant permissions and scan their SafeCall-generated QR. Client IT must qualify restrictive camera, notification, network, Android background/power, and other device policies against the approved device matrix.

Store payment rules change and final treatment belongs to store review. Recheck the current Apple App Review Guidelines and Google Play payments policy for each candidate. The factual narrative does not itself claim policy pre-approval or an exemption.

Supported platform and accessibility baseline

P0-04 approves this launch support boundary:

PlatformMinimumRequired physical OS coverage
iPhoneiOS 17iOS 17, 18, and 26
iPadiPadOS 17iPadOS 17, 18, and 26
Android phone/tabletAndroid 12 / API 31 on Google Play-certified devicesAndroid 12/12L, 13, 14, 15, and 16 / API 31–36

Keep Android target/compile API 36 and verify 16 KB native-page compatibility from the release AAB. Current source floors of iOS 13 and Android API 24 are implementation defaults, not support promises; P3/P4 must set and verify explicit iOS 17/API 31 floors before release.

Supported form factors and orientations:

  • iPhone: portrait and landscape left/right; no upside-down support;
  • iPad: all four orientations;
  • Android phones/tablets: portrait and landscape;
  • all supported devices require a functioning camera for QR provisioning.

Foldables and Chromebooks are not separately certified. macOS, Windows, Linux, web, visionOS, wearables, Android Auto, CarPlay, Fire OS, devices without supported Google Play distribution, and devices without a functioning camera are outside launch support.

Android OEM tiers:

TierScopeLaunch rule
Tier 1 — requiredGoogle Pixel/AOSP baseline and Samsung GalaxyFull delivery, background, reboot, Doze, upgrade, soak, orientation, tablet, and accessibility matrix passes
Tier 2 — conditional by model/OSXiaomi/Redmi/POCO, Motorola/Lenovo, OnePlus/Oppo/RealmeOnly the tested model/OS combination is supported after documented battery/background exceptions pass
Tier 3 — unsupported until qualifiedno-GMS Huawei, Fire OS, uncertified/unknown OEMs, rooted/custom ROMs, EOL devices/OSes, restrictive profiles blocking required capabilitiesNo support commitment; a family or install result is not evidence

Battery exceptions must be evidence-driven, least-privilege, device-specific, documented in English/Czech, and approved by client IT. Tier 1 must not depend silently on an undocumented exception. Remove a Tier 2 model/OS from support if approved settings cannot pass. Force-stop/force-quit is a documented platform limitation. Any supported-tier core alert-path failure, unresolved Android FGS/iOS APNs blocker, inaccessible critical flow, or failed permission recovery is a no-go rather than “best effort.” Waivers require the P0-05 authority (Thomas Minitsios), owner, rationale, expiry, and review date.

Every generally available supported OS major must appear in the physical matrix. The matrix must collectively cover iPhone, iPad, Android phone/tablet, Pixel/AOSP, and Samsung, with minimum and current OS coverage for each platform. Tier 2 evidence applies only to the exact tested model, OS, policy profile, and battery settings.

The launch-blocking accessibility baseline applies in English and Czech on physical supported devices:

  • complete onboarding, QR scan, permission recovery, Active/Archive, notification detail, pause/resume, rescan, and reset with VoiceOver and TalkBack;
  • meaningful spoken names for actions, state/error feedback, emoji/timestamps, scanner controls, and permission status;
  • WCAG 2.2 AA critical flows, including 4.5:1 normal-text and 3:1 large-text/UI component contrast;
  • 200% text scaling without clipped/lost content or unreachable primary actions across supported form factors/orientations;
  • minimum 44×44 pt iOS and 48×48 dp Android action targets;
  • logical visible focus plus keyboard/switch access where platform-supported;
  • no critical task dependent on animation and honored reduced-motion settings;
  • camera and notification denial/revocation explain the consequence, open system Settings, and recover successfully after return without a dead end.

This section defines requirements, not current conformance. The app has no complete semantics/a11y evidence, no complete permission-denial recovery, no executed device/OEM matrix, unverified tablet/orientation layouts, an unresolved Android background architecture, and unproven iOS killed-state delivery.

Required ownership record

Before a release starts, fill these fields in the release ticket. Do not infer an owner from who has a credential on one workstation.

Roadmap P0-05 approves the default launch ownership and operating class below. Per-release Apple/Google/signing fields remain P3 verification tasks and are not proven merely because the default owner is named.

FieldRequired value
Release ownerDefault: Thomas Minitsios (P0-05); record the named person coordinating this release
Go/no-go approverThomas Minitsios (P0-05 authority and backup); authorized to release, halt, or grant an expired-dated waiver
Apple account ownerLegal entity, Team ID, account holder, backup holder — verify in P3; do not infer from the bundle namespace
Google account ownerLegal entity, developer account ID, backup holder — verify in P3
Signing custodianPrimary and recovery custodians for each platform — verify in P3
ntfy/push ownerOwner of test and production ntfy/APNs/FCM services — default accountable owner Thomas Minitsios
Privacy/legal approverOwner of policy text and store-form answers — default accountable owner Thomas Minitsios
Regulatory/DSA ownerThomas Minitsios for the approved non-medical Czech launch; external counsel if scope, health functionality, medical claims, or assumptions change
Device/accessibility evidence ownerNamed P4 owner for OS/form-factor/OEM matrices, WCAG/AT evidence, exceptions, and expiry review — default accountable owner Thomas Minitsios
Support leadSafeCall support channel (no standalone Keryx mailbox); Czech business hours Mon–Fri CET/CEST; next-business-day first response; same-business-day acknowledgment of supported-tier core-path incidents by the go/no-go owner; escalation via GitLab plus the SafeCall account path; no public status page, 24/7 desk, or emergency-dispatch SLA. Actual mailbox/phone/URLs stay in controlled records
Client enablement/content ownerSafeCall-aligned listing copy, screenshots, install/support pages, and client communication — default accountable owner Thomas Minitsios
Telemetry postureNo analytics or crash SDK at launch; no administrator identifiers in this repository; client-reported diagnosis until P6-05 approves minimum signals
Candidate sourceCommit SHA, branch, annotated tag
Planned availabilityCzech Republic only; platforms and staged rollout percentages. Do not invent beta or production calendar dates until remaining P1–P4 launch blockers are closed or explicitly accepted

Version and source policy

Before every release, update version in keryx/pubspec.yaml:

yaml
version: 1.0.1+2

The part before + is the public version. The number after + is the build number and must increase for every uploaded build, including rejected or abandoned candidates. Never reuse an App Store or Play build number.

Use bun keryx from the repo root for a store-candidate cut: it prompts for the bump type and commit message, then analyzes, tests, builds the signed AAB and IPA, verifies, commits, tags keryx-vMAJOR.MINOR.PATCH, and pushes to origin. Store upload stays manual (Play Internal and Internal TestFlight). bun release:mobile releases the separate SafeCall Nav app and must not be used for Keryx. bun run release:keryx remains the no-git rebuild when the recorded artifacts are gone and the pubspec version must not change.

Approved source naming per versioning policy:

  • annotated tag: keryx-vMAJOR.MINOR.PATCH;
  • candidate record: public version plus platform build number;
  • release notes derived from keryx/CHANGELOG.md, not the full monorepo history;
  • one compatibility statement for the QR schema, minimum SafeCall version, ntfy requirements, and supported OS versions.

Release types

TypeVersion intentMinimum path
First public releaseEstablish product and store recordsAll roadmap gates G0–G5
Routine patchCompatible fixes and small improvementsFull automated gates, focused regression, internal store track, staged production
Routine minorCompatible features or material UX changesFull matrix, updated screenshots/forms/docs where affected, beta, staged production
MajorCompatibility or product-positioning changeNew migration/compatibility plan, client communication, pilot, all affected launch gates
Urgent hotfixSevere production defectHotfix authority, risk-based focused matrix plus mandatory core smoke, expedited staged release
Security releaseVulnerability or credential compromiseIncident process, secret rotation when needed, coordinated disclosure, fixed build, client notice

No version is “documentation only” when the binary, SDKs, permissions, data flows, support URL, privacy answers, or store metadata change.

Canonical store-content packet

Create one version-controlled content packet and use it for both stores. The approved listing copy lives in docs/gtm/keryx/store-listing-copy.md (P2-02). Screenshot sizes, shot list, sample data, and capture checklist live in docs/gtm/keryx/store-screenshot-kit.md (P2-03). The full packet must also contain:

  • English and Czech public app name, subtitle/short description, long description, keywords, and store promotional text, all subordinate to SafeCall;
  • sourcectl publisher/seller, copyright, Business categories, adult administrator audience, final questionnaire-derived age/content ratings, Czech Republic availability, and free price;
  • product URL, install URL, support URL, privacy URL, terms/EULA URL, monitored email, and review contact phone;

Draft English source for privacy, terms, and support (P1-06) is in docs/gtm/keryx/legal/ with planned path suffixes /keryx/privacy, /keryx/terms, and /keryx/support under a sourcectl-controlled {public_base} from controlled records. URL map and landing copy are in docs/gtm/keryx/public-web-pages.md (P2-04). Those URLs are not live until HTTPS deploy; do not paste invented hosts into store consoles.

  • icon and feature-graphic sources;

Use the approved visual brief in docs/gtm/keryx/visual-identity.md (P2-01) for names, mark colors (#003087 / #FFFFFF), and asset QA. The megaphone mark and Android adaptive/round/monochrome kit are in source (7 September 2026). Wordmark artwork remains open; do not treat store listing graphics as final until P2-03 / #125.

  • required screenshot sizes and captions for each supported device class and locale, including current iPhone, supported iPad, Android phone/tablet, and Play feature-graphic requirements; screenshots show friendly SafeCall alert categories, scan-on-own-device QR provisioning, and Active/Archive;
  • privacy-safe sample alert data and repeatable capture instructions;
  • reviewer explanation that Keryx is an included app for administrators of a separately contracted SafeCall physical/building deployment, that the QR configures connectivity rather than purchasing/licensing/unlocking paid digital content, and that no Keryx account, checkout, subscription, paid SKU, in-app purchase, external purchase call to action, standalone purchase, or manually configured ntfy client is offered;
  • installation-only MDM wording that distinguishes public-app assignment from unsupported managed configuration or zero-touch provisioning;
  • version-specific release notes and compatibility statement;
  • Apple privacy/encryption answers and Google Data Safety/app-content answers;

Use the approved Apple answers and checklists in docs/gtm/keryx/apple-privacy-compliance.md (P1-07) when filling App Store Connect. Generate and archive the Xcode privacy report from the production-signed candidate under #110; do not treat the packet alone as submission evidence.

Use the approved Play Data Safety, permissions, FGS, and App content answers in docs/gtm/keryx/play-data-safety.md (P1-08) when filling Play Console. Re-verify against the production-signed AAB under #109; console submission without unresolved warnings remains #125. Do not treat the packet alone as submission evidence.

  • foreground-service declaration text and demonstration video when required;
  • availability and phased-rollout plan.

Do not type final copy ad hoc into a store console. Peer-review the packet, then record the content revision or commit in the release ticket.

The packet must not invent an independent Keryx value proposition, target consumer traffic, or suggest that downloading the app grants access without SafeCall. ntfy may be described in technical review/privacy evidence where required, but not as an administrator setup step.

The earlier draft phrase “SafeCall safety notifications for your building” may be used only when consistent with the approved claims and delivery limitations in docs/gtm/keryx/safety-claims.md (P1-10). P0-02 fixes Business categories, no health functionality, and a non-medical-device position; changing those answers requires a reopened regulatory decision.

Data-flow and privacy evidence

The release candidate uses:

  • camera access so an administrator can scan a QR code generated by their own SafeCall installation;
  • notification permission, including badges and sound, to display alerts;
  • network access to a customer-configured ntfy service;
  • local preferences for the ntfy URL, topic names, labels, pause/debug state, and recent notification history;
  • native platform storage for background subscription state;
  • APNs/ntfy upstream push on iOS when production infrastructure is enabled;
  • an Android foreground service and boot/package-replaced receiver in the current architecture.

Keryx does not currently require a SafeCall login or admin JWT. That does not prove “no data collection” or “no personal data”: alert text can contain device names, MAC addresses, asset names, locations, or person-associated operational information, and the configured ntfy operator may process connection and push metadata. P1 must classify the real production payloads and SDK behavior.

For every candidate:

  1. Generate and archive the Xcode privacy report and dependency inventory. Use the approved ownership inventory in docs/gtm/keryx/dependency-ownership.md (P1-09). Machine SBOM/CI remain #112. Verify that the vendored ntfy framework packages its privacy manifest and declares approved UserDefaults reason CA92.1; its current source manifest lists no accessed API types despite using UserDefaults.
  2. Inspect the AAB/IPA permissions, entitlements, SDKs, endpoints, and storage.
  3. Compare findings with the public privacy policy, Apple privacy nutrition label, Google Data Safety form, permission disclosures, and support docs.
  4. Record retention, deletion/reset, device backup, lock-screen visibility, ntfy/APNs/FCM roles, subprocessors, and any diagnostics or analytics.
  5. Reject the release if the forms and policies do not match the binary.

Never put production credentials, real client topics, names, MAC addresses, locations, or incident data in screenshots, reviewer QR codes, issue attachments, or release evidence.

Apple App Store

One-time account and signing setup

P0-01 names sourcectl as the intended account owner, but do not treat the bundle ID as evidence that the account, legal registration, roles, or recovery controls are correct. Verify them through P3 before creating the app record.

  1. Verify Apple Developer Program and App Store Connect agreements, legal entity, tax/contact data, Account Holder, admin, developer, marketing, support, and backup access. Require 2FA and a recovery procedure.
  2. Register or verify the explicit App ID com.sourcectl.keryxapp and require an iOS/iPadOS 17 deployment target in the project, pods, archive, and listing.
  3. Enable only approved capabilities, including Push Notifications and Background Modes → Remote notifications.
  4. Create the App Store Connect iOS app record with Keryx for SafeCall, bundle ID com.sourcectl.keryxapp, English primary metadata, Czech localization, Business as the primary category, and Czech Republic-only availability. Declare sourcectl as an EU trader and verify the controlled organization identity plus the public address, phone, and email before submission.
  5. Configure distribution signing and provisioning. The source entitlement contains a development value, but the signed archive and distribution profile determine the final entitlement. Inspect the archive and require aps-environment = production; do not infer the final value from source alone. See iOS signing for the approved packet, ExportOptions.plist, and bun run verify:keryx-ipa.
  6. Create and review export options for the chosen App Store distribution method (committed at keryx/ios/ExportOptions.plist).
  7. Record certificate/profile/APNs-key owners, expiry, backup, revocation, and renewal dates without committing private material.
  8. Verify the current Apple SDK requirement on release day. As of the audit, submissions require Xcode 26 and the iOS/iPadOS 26 SDK or later.

Build and inspect the IPA

Open keryx/ios/Runner.xcworkspace when signing or capabilities need review. From the repository:

bash
cd keryx
flutter clean
flutter pub get
flutter analyze
flutter test
flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
cd ..
bun run verify:keryx-ipa

The operator store-candidate cut is bun keryx from the repo root (bump, analyze, test, signed AAB+IPA, verify, commit, tag, push). It fails closed without Android key.properties / keystore and without iOS distribution signing. It does not upload. Rebuild the current version without git with bun run release:keryx. Operator portal steps: operator-actions.md.

Inspect and archive:

  • resolved bundle ID, public version, build number, minimum OS, architectures, signing identity, provisioning profile, and entitlements;
  • production aps-environment, remote-notification background mode, camera and notification purpose strings, privacy manifests, required-reason APIs, SDK signatures, and encryption/export-compliance answer;
  • APNs device-token registration and rotation reaching the authenticated provider rather than ending in an empty callback;
  • IPA checksum, archive, symbols, Xcode privacy report, dependency lockfile, source commit, and build log.

Reject the candidate if its minimum is below iOS/iPadOS 17, the device-family or orientation declarations exceed the approved support matrix, or the archive cannot prove the required production signing, entitlements, and architectures.

TestFlight and review

  1. For the first internal upload, follow Internal TestFlight: Transporter on GLaDOS (or Xcode Organizer), wait for processing, answer HTTPS-only export compliance, and attach 1.0.0 (3) to Internal Testing.
  2. Resolve every TestFlight processing warning before treating the build as a candidate (details in that how-to).
  3. Keep this first pass on internal TestFlight only. External TestFlight is required when the P4/P5 beta plan calls for representative client administrators.
  4. Install from TestFlight on physical supported devices and run the complete release matrix below.
  5. Verify the app forwards APNs device-token registration and token changes to the authenticated delivery provider. The current callback discards the token, so this gate cannot pass without remediation.
  6. Verify production APNs/ntfy upstream push, message caching, poll_request, token invalidation, and recovery behavior in foreground, background, and terminated states.
  7. Complete privacy nutrition labels, encryption/export compliance, the honest age-rating questionnaire, Business category, “not a regulated medical device” answer, URLs, English/Czech screenshots and release notes, and Czech Republic availability from the approved content packet. The expected rating is 4+; return to P0-02 if the questionnaire produces a higher result.
  8. In App Review Information provide a monitored contact, non-expiring SafeCall-style sample QR with friendly categories, reachable isolated notification service, safe sample messages, exact administrator test steps, expected limitations, and the approved free-companion commercial fact block. State explicitly that the QR configures connectivity and selected alert categories rather than purchasing, licensing, or unlocking paid digital content. Reviewers must not be asked to configure ntfy or topics. Keep the service live for the entire review.
  9. Submit the already-tested build and archive all review correspondence.

Never mark “no data collection” from the absence of login or analytics alone. The final answer comes from the candidate data-flow and SDK audit.

Google Play Store

One-time account and signing setup

  1. Verify the approved legal publisher, Google Play organization account, legal identity/address and required organization data, public developer phone/email, private contact data, admins, release managers, app support, backup access, 2FA, and recovery process.
  2. Create the app record with package com.sourcectl.keryx, English as the default language, a complete Czech listing, app/free answers, Business category, Czech Republic-only availability, Android 12/API 31 minimum, and the approved phone/tablet device catalog.
  3. Enroll in Google Play App Signing. Create an upload key outside the repository, store it in NAS secrets/ (secret store), document custodians and recovery, and archive only public certificates/fingerprints. See Android signing for the approved packet, key.properties.example, and bun run verify:keryx-aab.
  4. Configure ignored local or CI signing inputs from key.properties. Release builds fail closed without upload credentials; debug signing remains for local debug builds only.
  5. Verify an explicit API 31 minimum and the required target/compile API on release day. New apps and updates require Android 16 / API 36 from 31 August 2026.
  6. Resolve the current foreground-service architecture before creating a production release. Android 15+ applies an aggregate six-hour timeout to dataSync foreground services and restricts background/boot starts; the current perpetual sticky service, wake lock, and boot receiver are not assumed viable. Archive the replacement or proof, policy decision, declaration, demonstration video, timeout handling, runtime tests, and fallback behavior.

Build and inspect the AAB

After production signing has passed its gate, prefer bun keryx from the repo root for a new store candidate, or bun run release:keryx to rebuild the current pubspec version without git. The standalone AAB path remains:

bash
cd keryx
flutter clean
flutter pub get
flutter analyze
flutter test
flutter build appbundle --release
cd ..
bun run verify:keryx-aab

Inspect and archive:

  • package name, public version, version code, minimum/target/compile SDK, supported ABIs, 16 KB native-page compatibility, signing certificate fingerprint, and debuggable status;
  • merged permissions, services, receivers, exported components, foreground service types, network security behavior, cleartext behavior, SDK inventory, and Play pre-launch warnings;
  • AAB checksum, mapping/symbol files where produced, dependency lockfile, source commit, build log, and signing verification.

Reject the candidate if its minimum is below API 31, it is debug-signed, debuggable, below the target API deadline, fails 16 KB native-page validation, unexpectedly permits cleartext, exceeds the approved device catalog, or declares a foreground service that does not match the approved design and Play form.

Play test tracks and review

For the first Internal install of the working-loop AAB, follow ntfy auth dual-run and Play Internal Part E (OA-124-play-internal). Do not start Production from that page.

  1. Upload the signed AAB to Internal testing.
  2. Resolve automated pre-launch, policy, compatibility, and device-catalog findings.
  3. Install from Play on physical devices across the approved P0-04 OS/form-factor/orientation and Tier 1/Tier 2 OEM matrix, then run the complete release matrix.
  4. Promote the same artifact to Closed testing when the pilot plan requires external client administrators. Meet any account-specific testing eligibility requirements shown by Play Console.
  5. Complete the approved listing packet and every App content section, including privacy policy, ads, app access, target age 18+ only, the honest content-rating questionnaire, Data Safety, permissions, foreground service, and the Health apps declaration with no health functionality. The expected IARC result is Everyone; return to P0-02 if the questionnaire differs.
  6. For QR-based review access, publish a non-expiring static URL containing the SafeCall-style reviewer QR, friendly-category context, and exact administrator instructions. Use the isolated test notification environment, not a client deployment, and do not require manual ntfy/topic setup. Include the approved free-companion and QR-connectivity fact block so review does not mistake setup for an externally purchased digital-content unlock.
  7. Upload the approved foreground-service demonstration and explain why the service is core, user-visible, non-deferrable, and compliant only if the P1 decision supports that claim.
  8. Send the already-tested build for review and archive all correspondence.
  9. Promote through a staged production rollout only after both store approval and the release go/no-go record.

Do not pre-answer Data Safety with “no collection” or “no sharing.” Derive each answer from the tested binary, SDKs, notification payloads, ntfy/push operators, storage, diagnostics, and published privacy policy.

Release-candidate test matrix

Run this checklist from TestFlight and Google Play Internal/Closed testing on physical devices. Record device model, OS, OEM settings, app version/build, SafeCall version, ntfy environment, result, evidence, and tester.

  1. In SafeCall, select friendly alert categories and generate a standard Keryx QR code. Verify the administrator-facing flow does not expose ntfy/topic terminology and that the payload contains no admin, MQTT, publishing, or unrelated credentials.
  2. Install the release build.
  3. Exercise first launch before permissions, deny camera, verify a clear consequence and system-Settings route, grant camera, return successfully, and scan the QR code without a dead end. Revoke camera while configured, resume, and verify recovery. Confirm unconfigured guidance directs the administrator to their own SafeCall installation rather than to a separate provisioning persona.
  4. Confirm setup and the notification list are displayed without server URLs, topic names, subscription instructions, or third-party ntfy setup.
  5. Deny notifications, verify the app persistently explains the delivery consequence and system-Settings recovery, then grant notifications and return successfully. Revoke while configured, resume, and verify recovery without a dead end.
  6. Confirm the app starts receiving automatically and shows an empty notification list.
  7. Publish safe test messages through selected and unselected internal category mappings. Confirm only authorized selected-category messages arrive.
  8. Confirm local notification title/body, sound, priority, tags, timestamp, badge, tap behavior, and Active entry.
  9. Mark notifications read and confirm they move to Archive; delete archived messages and prove cache polling does not resurrect them.
  10. Verify standard detail mode hides topic, message ID, sent time, and raw payload; verify those fields only with an explicitly generated debug QR.
  11. Pause notifications, publish a message, confirm no live alert/badge, resume, and confirm the documented cache-recovery behavior.
  12. Select replacement friendly categories, scan the new QR, and verify old internal subscriptions stop, new ones start, and retained/cleared history follows the approved migration policy.
  13. Reset the app and verify configuration, native subscription state, history, tombstones, and badge are cleared; reprovision successfully.
  14. Test offline launch, Wi-Fi/mobile transitions, DNS/TLS failure, ntfy restart, cache expiry, duplicate/replayed message, clock skew, and recovery.
  15. Minimize and close Android; verify the approved foreground behavior and persistent system notification.
  16. Reboot Android without opening Keryx; verify expected restart after unlock and delivery. Repeat while paused and under each supported OEM battery tier.
  17. Verify Android Doze/battery optimization behavior and the exact administrator-facing limitation or remediation.
  18. On iOS, verify foreground, background, and terminated delivery through the production-equivalent APNs/ntfy path plus poll-on-resume recovery.
  19. Verify Focus/Do Not Disturb, mute, lock-screen preview, notification-summary, force-stop/force-quit, and permission-revocation limitations match docs.
  20. Install the previous store/test build, provision it, add Active/Archive history, then update through the store channel. Verify configuration, history, badge, native service state, and delivery survive.
  21. In both English and Czech, complete all P0-04 critical flows with VoiceOver/TalkBack; verify meaningful spoken names, logical visible focus, keyboard/switch access where supported, 200% text without lost content, 4.5:1 normal-text and 3:1 large-text/UI contrast, 44 pt/48 dp targets, every approved phone/tablet orientation, and reduced motion without a blocked task.
  22. Verify every support, privacy, terms, SafeCall-related product, and install URL from the app and store packet is public, correct, monitored, available without login, and explicit that Keryx is not independently usable.
  23. Complete a long-running delivery soak for the approved duration and record latency, missed/duplicate messages, reconnects, crashes, power impact, and OEM/OS conditions.
  24. Confirm the evidence set covers every approved OS major, iPhone, iPad, Android phone/tablet, Pixel/AOSP, and Samsung, including minimum and current platform versions. Confirm each Tier 2 claim names the exact model, OS, policy profile, battery settings, and result.

Candidate preparation and release record

Create one GitLab release work item and attach or link a durable record with:

text
Release type:
Release owner: Thomas Minitsios (default from P0-05)
Go/no-go approver: Thomas Minitsios (P0-05 authority and backup)
SafeCall companion / administrator-only model verified:
Free companion / separately contracted deployment narrative verified:
QR connectivity-not-purchase explanation verified:
No account / checkout / subscription / IAP / external purchase CTA verified:
Public-app MDM install-only limits verified:
Availability: Czech Republic only
App and listing locales: English primary/default; Czech complete
Apple / Google category: Business / Business
Target audience: SafeCall administrators aged 18+
Apple / Google rating result:
Health functionality / regulated medical device answer:
EU trader and controlled public-contact evidence:
Support class: SafeCall channel; Czech business hours; next-business-day first response; same-business-day core-path acknowledgment; no standalone Keryx mailbox / public status page / 24/7 / emergency dispatch
Telemetry posture: no analytics or crash SDK at launch; client-reported diagnosis
Date policy: no invented beta/production calendar date until P1–P4 launch blockers are closed or accepted
Public version:
iOS build:
Android version code:
Source commit and annotated tag:
SafeCall compatibility:
QR schema:
iOS/iPadOS minimum and tested majors:
Android minimum / target / compile SDK:
16 KB native-page verification:
Form-factor / orientation evidence:
Dependency-lock hash:
AAB path and SHA-256:
IPA/archive path and SHA-256:
Symbols / mapping paths:
Signing certificate fingerprints:
CI and test evidence:
Device/OS/OEM matrix:
OEM tier / model / battery exception evidence:
VoiceOver / TalkBack / WCAG evidence:
200% text / contrast / target-size evidence:
Permission denial / revocation / recovery evidence:
Delivery-soak evidence:
Privacy report revision:
Apple privacy/encryption answers revision:
Play Data Safety/app-content answers revision:
Listing-content revision:
Reviewer QR/environment check:
Known limitations and accepted risks:
Support coverage:
Planned rollout:
Decision and timestamp:
Store submissions and review correspondence:
Production release timestamps:
Observation results:
Post-release sign-off:

The record may link to a restricted vault or evidence system. Never paste private keys, passwords, bearer tokens, real client QR payloads, or sensitive production data into GitLab.

Before building:

  1. Confirm all work intended for the release is reviewed and all unrelated working-tree changes are excluded.
  2. Resolve the public version/build numbers and create the release work item.
  3. Re-run current Apple/Google policy and SDK-deadline checks.
  4. Confirm test/reviewer/production ntfy and APNs/FCM owners are available.
  5. Confirm public English/Czech privacy/support/terms/install URLs, the P0-05 SafeCall support class and coverage, sourcectl EU trader evidence, and verified Apple/Google organization and public-contact records. Confirm no invented beta/production calendar date is claimed before P1–P4 launch blockers are closed or accepted.
  6. Confirm the administrator journey uses friendly categories and QR provisioning, and that no public/reviewer artifact presents Keryx as standalone, presents QR setup as payment/licensing/unlock, includes an external purchase call to action, or requires manual ntfy/topic setup.
  7. Confirm complete English/Czech app, SafeCall provisioning, listing, screenshot, release-note, permission/help, and client-material parity.
  8. Confirm MDM wording is limited to assignment/installation of the public app and does not promise managed configuration, injected credentials, zero-touch setup, custom/private binaries, silent configuration, or unverified restrictive-profile compatibility.
  9. Confirm explicit iOS/iPadOS 17 and Android API 31 floors, API 36 target/compile values, release AAB 16 KB compatibility, approved form-factor/orientation declarations, and non-target platform exclusions.
  10. Confirm all Tier 1 and claimed Tier 2 device evidence, English/Czech battery guidance, client-IT approvals, accessibility criteria, and camera/ notification denial/revocation recovery have passed without an expired waiver from the P0-05 go/no-go authority.
  11. Confirm the release candidate does not ship an analytics or crash SDK and that any later signal still requires a privacy-approved purpose, retention, and disclosure decision.
  12. Freeze the approved listing packet and policy-form revisions.
  13. Run automated server/web contract gates when Keryx provisioning or QR schema depends on those components, plus Keryx analyze/tests and native builds.
  14. Build once from the reviewed source, calculate checksums, and promote that exact artifact through test and production tracks.

Go/no-go review

The named approver records GO, NO-GO, or GO WITH ACCEPTED RISK. At minimum, review:

  • roadmap gates affected by the release;
  • unresolved launch blockers and store warnings;
  • signing identities, entitlements, permissions, target SDK, and build numbers;
  • automated, supported OS/form-factor/orientation, Tier 1/Tier 2 OEM, upgrade, WCAG/assistive-technology, permission-recovery, 16 KB, and soak evidence;
  • production-equivalent Android and iOS killed-state delivery;
  • privacy/data/legal/support and listing consistency;
  • the SafeCall companion relationship, administrator-only persona, friendly category language, QR-hidden configuration, and absence of standalone marketing;
  • reviewer environment health;
  • client prerequisites and compatibility;
  • support staffing, incident contacts, rollback limitations, rollout stages, observation windows, and stop thresholds;
  • battery/managed-device exceptions and accepted risks with owner, client-IT approval where applicable, expiry, and review date.

Silence is not approval. A failed or expired gate returns the release to the appropriate GitLab work item.

Production rollout

Use staged/phased release unless the go/no-go owner records why an immediate full release has lower risk.

For each stage record:

  • platform, countries, percentage, start/end timestamp, and app build;
  • expected install/update population;
  • crash, delivery, duplicate/missed-alert, support, review, and policy signals;
  • client and support feedback;
  • stop thresholds and who is watching them;
  • decision to continue, hold, halt, or supersede.

Suggested shape after the P5 issue approves actual values:

  1. Named pilot client administrators and internal SafeCall operators.
  2. Small public percentage with an observation window.
  3. Increased percentage after explicit review.
  4. Full selected-region availability.
  5. Post-release sign-off and handoff to P6 operations.

Do not promote one store merely to compensate for a rejected or untested build on the other without recording the platform split, client impact, and communications.

Routine update process

  1. Triage proposed changes and determine patch/minor/major impact.
  2. Review compatibility with supported SafeCall versions, QR schemas, stored configuration/history, native subscription state, ntfy, and minimum OS.
  3. Create the release ticket, assign owners, and update the changelog.
  4. Re-check SDK deadlines, dependencies/advisories, permissions, privacy/data flows, policies, screenshots, support docs, and store forms.
  5. Freeze scope, increment public/build versions, and build from reviewed source.
  6. Run automated gates, focused regressions, the mandatory core matrix, a store-channel upgrade from the previous production version, and the required device/soak subset.
  7. Upload to TestFlight/Internal testing (internal-testflight.md), then the approved external/closed track. Promote the exact artifact.
  8. Complete go/no-go, phased rollout, observation, client communication, and post-release sign-off.
  9. Update compatibility records, public release notes, support knowledge, and renewal/dependency inventory.

An update that changes the intended audience, SafeCall relationship, friendly category/QR journey, customer-facing transport abstraction, notification delivery, permissions, QR contents, local storage, ntfy authentication, analytics, legal entity, support URL, or public claims must reopen the affected P0/P1/P2/P4 gates.

Urgent hotfix and security release

The incident lead and release authority first classify:

  • administrator harm and safety impact;
  • confidentiality/integrity/availability impact;
  • affected versions/platforms/clients;
  • exploit or delivery-failure status;
  • whether to stop a rollout, unpublish availability, revoke credentials, or advise a temporary operational workaround.

Then:

  1. Open an incident and hotfix release ticket with a single scoped fix.
  2. Preserve evidence and rotate/revoke credentials before code work when compromise requires it.
  3. Branch from the approved production source, not an unrelated development branch.
  4. Increment build numbers; never replace a submitted build.
  5. Run automated gates plus mandatory provisioning, receive/display, pause/resume, reset, upgrade, signing, permission, and platform-background checks. Add focused regression and device tests for the incident.
  6. Re-evaluate privacy/forms/listing text when the fix changes data or platform declarations.
  7. Use store expedited-review channels only when eligible and provide a concise, factual impact statement and reviewer access.
  8. Stage the fixed release as quickly as risk permits, monitor continuously, and notify affected clients/support.
  9. Publish a coordinated advisory when required, then complete a post-incident review and merge durable tests/runbook changes.

Urgency does not authorize debug signing, reused build numbers, skipped core tests, hidden policy changes, or unrecorded production credentials.

Stop rollout, rollback, and store rejection

Stop rollout

Halt immediately when a defined threshold is crossed, a core alert path fails, signing or policy evidence is wrong, sensitive data is exposed, reviewer/client credentials are compromised, or the release authority declares no-go.

Actions:

  1. Pause the phased/staged release in the affected console.
  2. Record current reach, affected builds, symptoms, and timestamps.
  3. Notify support, incident owner, pilot clients, and stakeholders.
  4. Preserve logs/evidence without collecting unnecessary personal data.
  5. Decide between configuration mitigation, client instruction, superseding hotfix, temporary unavailability, or accepted hold.

Rollback limitation

Apple and Google generally do not provide an immediate public downgrade to an older store binary. Existing administrators may retain the faulty version. The normal recovery is to halt expansion and release a higher build number. Server-side mitigation must preserve compatibility and must not silently disable a safety workflow without client communication.

Review rejection

  1. Archive the exact rejection text and affected guideline/policy.
  2. Keep the submitted artifact immutable.
  3. Decide whether the response is clarification/evidence, metadata correction, infrastructure correction, or a new binary.
  4. Update the GitLab issue, roadmap risk, forms/runbook, and tests where the rejection exposed a systemic gap.
  5. Use a new build number for any changed binary.
  6. Re-run the affected test and go/no-go gates before resubmission.

Signing, credential, and account continuity

Maintain a restricted inventory with:

  • Apple membership, Team/App IDs, Account Holder/admins, distribution certificates/profiles, APNs keys, App Store Connect API keys, expiry and revocation;
  • Google developer account/admins, Play App Signing certificate, upload key, service accounts/API access, recovery and verification;
  • reviewer/test and production ntfy hosts, scoped credentials, APNs/FCM integration, domains/TLS, caching and retention;
  • support/product/privacy/terms domains, mailboxes, DNS/TLS, and owners;
  • Flutter/Xcode/Android SDK and target-API deadlines;
  • dependency and vendored-plugin owners (see docs/gtm/keryx/dependency-ownership.md).

At least two authorized people must be able to recover release capability when a second person is available. P0-05 currently names Thomas Minitsios as both go/no-go authority and backup; the single-person concentration is a named risk reviewed when P3-06 verifies account recovery and at the first P5 go/no-go. Perform a documented recovery drill before launch and at the P6 cadence.

Compatibility, deprecation, and end of life

Maintain a compatibility matrix across:

  • Keryx public version/build;
  • supported iOS/iPadOS/Android and OEM tiers;
  • minimum/maximum tested SafeCall server and web versions;
  • QR payload type/version and migration behavior;
  • ntfy server version/features, cache settings, authentication scheme, and push prerequisites;
  • stored configuration/history migration;
  • store availability and support end date.

Before dropping compatibility:

  1. measure or otherwise determine affected clients without violating the P0-05 no-analytics/crash-SDK telemetry posture;
  2. provide advance administrator notice and a tested migration path;
  3. update listings, support docs, client prerequisites, and policy forms;
  4. preserve a safe failure mode with clear support instructions;
  5. define whether old builds continue, are blocked, or lose backend compatibility, and test that behavior.

For end of life, approve dates and communications, stop new provisioning, remove or unpublish store availability as appropriate, revoke test/production credentials, document local reset/uninstall and client data handling, archive release evidence, and retain the support/security contact for the stated period.

Post-release review

At the end of every observation window:

  • confirm the production build and listing versions in both stores;
  • review delivery reliability by approved platform/OEM tier;
  • review crashes or the approved privacy-preserving stability signal;
  • review support incidents, first-response/resolution, store feedback, and policy warnings, including unsupported standalone-install expectations;
  • verify public URLs, reviewer environment, certificates, credentials, target SDK, and dependencies remain healthy;
  • close the release ticket only after owners accept open follow-ups;
  • feed defects into GitLab and decisions/accepted risks into the GTM roadmap.

Quarterly, repeat the store-policy, SDK, dependency, credential, support, compatibility, accepted-risk, and roadmap review described by P6.