Skip to content

Keryx versioning and compatibility policy

Approved: 26 August 2026

This document is the P3-05 policy packet for Keryx for SafeCall: semantic version rules, monotonic build numbers, annotated source tags, changelog ownership, store release-note derivation, QR schema compatibility and migration, minimum SafeCall compatibility placeholders, downgrade behavior, abandoned-build handling, and launch support window.

It does not claim an automated release pipeline (#111), CI version gates (#112), store console paste (#125), QR v2 implementation in app or SafeCall server code, a numeric {min_safeCall} value (recorded at first release in #114), or the full compatibility/EOL matrix deferred to #130.

Purpose and non-goals

Purpose

  • Approve semver and build-number rules for keryx/pubspec.yaml.
  • Define annotated keryx-v* tags in the safecall monorepo.
  • Assign changelog ownership and map entries to store release-note templates.
  • Document QR schema evolution, stored-config migration, and coordinated v2 cutover expectations.
  • Record downgrade, abandoned-build, and launch support-window policy.

Non-goals

  • Implementing automated bump/tag in CI or release scripts.
  • Changing current QR parser code (v2-only; v1 scans are rejected with on-device copy).
  • Replacing this policy with CI-owned bumps. Current pre-release candidate is 1.0.0+3 (builds 1 and 2 were consumed by the Play internal draft and the first Internal TestFlight IPA).
  • Replacing SafeCall Nav (mobile/) versioning — mobile-v* tags remain Nav-only.

Current version baseline

FieldValueSource
Public version1.0.0keryx/pubspec.yaml (before +)
Build number3keryx/pubspec.yaml (after +)
ChangelogFirst-release noteskeryx/CHANGELOG.md
QR in codesafecall.keryx.ntfy.v2keryx/lib/models/keryx_config.dart
QR protocol targetsafecall.keryx.ntfy.v2provisioning-protocol.md

Semantic version rules

Public version uses MAJOR.MINOR.PATCH in pubspec.yaml (the part before +).

SegmentWhen to bumpExamples
PATCHCompatible bug fixes, small UX polish, dependency patches with no behavior change1.0.01.0.1
MINORBackward-compatible features, material UX changes, new optional QR fields that older apps ignore1.0.11.1.0
MAJORBreaking QR schema, breaking stored-config shape, minimum SafeCall bump that drops older servers, or product-positioning change requiring re-provisioning1.1.02.0.0

Align version intent with release types in Publishing Keryx (first release, routine patch/minor, major, hotfix, security).

Hotfix and security releases still bump at least PATCH (or MINOR/MAJOR when compatibility changes). Never ship a store candidate without incrementing the public version from the last promoted build unless the prior candidate was never uploaded and is discarded before any store record references it.

Build number rules

The integer after + in pubspec.yaml is the monotonic build number shared across iOS and Android for a given store candidate.

RulePolicy
MonotonicityEach uploaded or submitted candidate uses a build number strictly greater than any prior upload for the same platform store record
Cross-platformiOS and Android releases from the same public version may share one build number when built from the same tagged commit; single-platform releases still increment
Never reuseRejected, abandoned, or superseded candidates consume their build number — do not reuse after Play or App Store Connect assignment
Pre-upload bumpsIncrement before building when the previous candidate reached upload, even if not promoted to production

Example:

yaml
version: 1.0.1+2

1.0.1 is the public version; 2 is the build number.

Source tag policy

Keryx store artifacts are attributed to annotated tags in the safecall monorepo:

ItemPolicy
Tag formatkeryx-vMAJOR.MINOR.PATCH (e.g. keryx-v1.0.0)
Tag targetCommit that produced the signed AAB/IPA uploaded or submitted
Tag typeAnnotated tag with message: public version, build number, operator/date reference
Forbidden patternsDo not use mobile-v* (SafeCall Nav) or undecorated version tags for Keryx

Tag after verify scripts pass (verify:keryx-aab, verify:keryx-ipa) and before or immediately after store upload. Record tag name, commit SHA, and build number in the controlled evidence archive (#114).

Changelog ownership

ItemOwner
Canonical filekeryx/CHANGELOG.md
Policy approverThomas Minitsios (P0-05 RACI)
LanguageEnglish user-facing entries (Czech store fields derived per localization.md)
Monorepo root CHANGELOG.mdSafeCall server/product scope only — not Keryx store notes

Workflow:

  1. Accumulate user-visible changes under ## Unreleased during development.
  2. On release cut, move entries to ## X.Y.Z — YYYY-MM-DD (or launch date TBD).
  3. Derive Apple/Google release notes from the released section (see below).
  4. Archive changelog excerpt + store paste in #114 evidence.

Release-note derivation

Map changelog sections to templates in store-listing-copy.md:

PlaceholderSource
{version}Public semver from pubspec.yaml / tag
{min_safeCall}Recorded per release in #114 evidence — TBD at G2 for first public release
{changes}Bullet list from changelog (omit internal/tooling-only items)

Rules:

  • First public release: use the fixed welcome/compatibility templates; do not invent {min_safeCall} until G2 records it.
  • Routine updates: paste {changes} from the released changelog section.
  • Hotfix: one-line summary acceptable when the fix is narrow; still log full detail in CHANGELOG.md.
  • Major / QR cutover: include explicit re-provision or minimum SafeCall statement; coordinate with client enablement (#120).

QR schema compatibility

SchemaStatusPolicy
safecall.keryx.ntfy.v1Current codePre-launch legacy; must not be emitted for production QR after v2 cutover
safecall.keryx.ntfy.v2Approved protocol (#95)Launch production target; requires subscribe_auth per provisioning-protocol.md

Closing #113 approves policy only. v2 cutover is a coordinated release gate:

  • SafeCall admin UI stops emitting v1 QR.
  • Keryx rejects new v1 scans (fail-closed).
  • Stored v1 credentials are not silently upgraded — administrators re-scan v2 QR.
  • ntfy requires HTTPS + ACL per #119 at cutover.

See provisioning-protocol fail-closed v1 migration rules for field-level detail.

Stored-config migration

On app upgrade when the QR schema is unchanged:

  • Preserve topics, friendly labels, server URL, and pause state in KeryxConfigStore (forward-only JSON shape).
  • Do not clear history unless the user runs reset or a documented migration requires it.

On v1 → v2 cutover:

  • No silent credential upgrade — require re-scan of v2 QR.
  • Reject opening or refreshing with stored v1 config after cutover build ships.
  • Document migration in release notes and client administrator guidance.

Future schema bumps follow the same rule: breaking stored shape → major version

  • explicit re-provision unless a forward-compatible reader is proven in #118 evidence.

Minimum SafeCall and ntfy compatibility

FieldLaunch policy
{min_safeCall}Placeholder until first public release evidence (#114); set at G2 go/no-go, not invented in docs
ntfy serverHTTPS-only; topic ACL and subscribe tokens per v2 protocol and #119 checklist
OS floorsiOS/iPadOS 17+, Android 12 (API 31)+ per P0-04 — stated in store templates

Each promoted release records {min_safeCall}, QR schema version accepted, and OS/API floors in the #114 controlled archive.

Downgrade behavior

ScenarioPolicy
App Store / Play rollbackStores do not roll users back to older builds; fixes require a new higher build
Sideload / manual install of older APK/IPAUnsupported for production administrators
Downgrade after schema migrationMay fail to connect or show stale config until re-provisioned with current QR
Major version downgradeNo guarantee of forward-compatible stored config

Administrators on outdated builds remain on best-effort support per support window below; security issues may force minimum-version enforcement in a future #130 matrix.

Abandoned and rejected builds

When a candidate fails verification, review, or go/no-go:

  1. Archive AAB/IPA checksum, build number, commit SHA, and rejection reason in #114.
  2. Mark the build abandoned in the release record — do not promote.
  3. Still consume the build number; increment before the next upload.
  4. Never promote an untested binary or one that skipped verify scripts.

Support window (launch policy)

Until #130 defines full EOL:

  • Supported: current store release + previous patch on the same minor (N and N−1 patch, e.g. 1.0.2 and 1.0.1 when 1.0.2 is current).
  • Best-effort: older patch/minor versions still on devices.
  • EOL matrix, store removal, forced upgrade: owned by #130 (P6-03).

Evidence handoff

Remaining workOwner issue
Reproducible bump/build/tag pipeline#111 — first recorded run 1 September 2026 did not bump or tag. Operator cut is bun keryx (bump, signed AAB+IPA, commit, keryx-v* tag, push). Store upload stays manual.
CI quality and version gates#112
Release records, checksums, {min_safeCall}#114
Store release-note paste#125
Full compatibility / EOL lifecycle#130
QR v2 implementation and cutoverPost-#95 delivery; coordinated with #119

Launch posture

Closing #113 approves versioning and compatibility rules. It does not claim:

  • Automated version increment or tagging.
  • QR v2 parsing in shipped binaries.
  • A numeric minimum SafeCall version.
  • Store release notes pasted or a production promotion.

Review record