Skip to content

Keryx operator close-out ​

Last updated: 2 October 2026 (next: OA-126-apple-resubmit; deny-all after public install + NSE)

One sitting (or several days of sittings) to execute remaining human / portal / secret-store rows for Keryx public launch.

Ariadne and Theseus Internal leftovers are not this sitting:

This page is the Keryx session playbook. It is not a second owed-list.

SurfaceRole
Keryx operator actionsStatus of Keryx rows (pending / later / done)
This pageOrder, machines, numbered steps, gates, evidence

After each chapter, tick the matching row done (date + Verify) in that log. Policy packets stay the source for why and extra depth.

Do not put passwords, keystores, .p12, .p8, PHCs, tk_…, recovery keys, QR photographs, or a filled {public_base} in this file, in git, in chat, or in GitLab. Record only where they live (NAS / Apple Passwords / portal).

How to use this page ​

  1. Unlock the NAS (Phase 0) if File Browser is empty. Phase 0, Phase 1, Phase 2, Phase 3 (OA-keryx-status-sidecar), OA-121-app-walk, and OA-116-device-a11y (skipped), OA-legal-cs, and OA-107-https are done. OA-123-review-host is done 20 September 2026. OA-125-listings is done 21 September 2026. Current chapter is OA-126-apple-resubmit after Apple rejected 1.0 (18) on 23 September 2026. Keep #126 open. Do not apply deny-all until OA-119-ntfy-cutover (#166) after public install + #165 NSE. Apple recovery stays after public launch.
  2. Walk remaining chapters in order. You may split days at phase boundaries.
  3. For later chapters, read the Gate first. If it fails, stop that chapter. Do not tick the row.
  4. After a chapter succeeds: NAS evidence (secret-free), tick the log row, add a secret-free GitLab note. Close the GitLab iid only when that issue’s remaining acceptance is this OA (see each chapter).
  5. Use the master checklist as the sitting scoreboard.

Ticking an OA is not the same as closing GitLab. Most Keryx residuals stay open (#112 SBOM / signed CI, #121 onboarding, #117 / #124 soak). #116 closed 20 September 2026. #107, #108, and #123 are already closed. #125 listings are done (closed). Store submit OA-126-submit is done (submitted 21 September 2026). Apple rejected 1.0 (18) on 23 September 2026. Resubmit is OA-126-apple-resubmit. Keep #126 open until both stores approve.

Do not apply ntfy deny-all until OA-119-ntfy-cutover. Do not unpublish Play. Do not upload a new IPA for this rejection.

Proof in this chat ​

After each numbered step, take the screenshot named under Paste. Drop it into this Cursor chat. The agent ticks the step from the picture.

If you already did a step: do not redo it. Open the resulting screen now and paste that.

Crop passwords, tokens, phone numbers, recovery keys. Never paste QR codes, tk_…, PHCs, .p12 / .jks files, or keystore passwords.

Global forbidden ​

Do not do any of these unless a later chapter’s gate is green and that chapter says to:

  • Set auth-default-access: deny-all on hetest2 (or any dual-run host) unless OA-119-ntfy-cutover’s gate is green
  • Press Play Send app for review again, or upload a new Keryx IPA. The Apple resubmit of the same 1.0 (18) binary is OA-126-apple-resubmit only. Do not request expedited review.
  • Unpublish the real Keryx listing, halt a live rollout, or file expedited review as part of a tabletop
  • Photograph a QR into chat, GitLab, or tickets
  • Paste tk_…, PHCs, recovery keys, or decoded QR JSON anywhere but Apple Passwords / the live ntfy host
  • Reuse TST000 topics or TST000 tokens as the Apple / Google reviewer environment
  • Put safecall-ops on a Keryx QR
  • Claim Ariadne store IDs cz.wantok.ariadne
  • Commit floor rasters, mar.json, or a live reviewer QR PNG
  • Invent {public_base} in git
  • Silently reuse https://safecall-lab.sourcectl.com as the Keryx store privacy URL
  • Register GLaDOS as a GitLab runner or inject signing CI variables
  • Add an analytics / crash SDK or a public status page
  • Sideload Keryx APKs for the administrator walk (store / Internal only)

Session kit ​

NeedWhat
OperatorThomas Minitsios (P0-05). Same person is Account Holder / Play owner
MacGLaDOS (signing / File Browser). MiniVan-3 optional
NASCT 500 nas 192.168.178.213. Unlock: nas-unlock.md
Secret storesecret-store.md
Apple PasswordsPassphrases, tk_…, recovery key location, ntfy user passwords
Notify hosthetest2 / https://notify.wantok.cz (ntfy 2.16). Deployer: ntfy-deployer.md
PhonesOne iPhone + one Android. Keryx 1.2.1 (8)+ from TestFlight / Play Internal (not 1.0.0+3)
GitLabMaintainer on sourcecontrollers/safecall. Shared runners for OA-112
{public_base}https://sourcectl.com (operator record 20 September 2026). English /keryx/* including /keryx/review placeholder are live 200s (OA-107, 20 September 2026). Do not use the lab host.

Already closed — do not re-run ​

IDWhat landed
OA-109-*Play app record, App Signing, upload keystore on NAS, MiniVan-3 AAB recovery
OA-110-*Push on com.sourcectl.keryxapp, ASC app CZ-only, IPA evidence, second-Mac recovery, Distribution .p12 on NAS
OA-111-pipelineLocal bun run release:keryx fail-closed pipeline
OA-112-ci-enableUnsigned GitLab slice green on master (pipeline 2858894786, 17 September 2026). Reopened the same day; #112 stays open
OA-132-intake-drill / OA-129-hotfix-tabletopNAS evidence/keryx/2026-09-17-oa-132-intake-drill.txt (1.05 KiB) and 2026-09-17-oa-129-hotfix-tabletop.txt (644 B). #132 and #129 stay open
OA-114-archive / apple-org / play-org / eu-traderNAS share, org roles, 2FA, EU trader. Residual recovery is OA-114-apple-recovery
OA-119-* (except cutover)ntfy auth dual-run, Firebase, APNs .p8, FCM on hetest2, deployer packet, first-device swipe-away on 1.2.1 (8)
OA-120-*English admin handbook + one-user install+scan. Czech handbook stays #108
OA-121-app-guide-docsEnglish app-onboarding-guide.md. Walk is OA-121-app-walk (done 19 September 2026)
OA-121-app-walkiPhone TestFlight 1.3.7 (18): onboarding, scan, pipeline test, pause/resume, Czech. NAS evidence/keryx/2026-09-19-oa-121-app-walk.txt (32 B). Do not close #121
OA-116-device-a11ySkipped 20 September 2026: trained hospital/admin operators; no VoiceOver/TalkBack walk; no WCAG claim. #116 closed
OA-legal-csCounsel reviewed EN+CS legal package 20 September 2026. DRAFT banners removed from English public HTML. Letter not in git. #108 closed
OA-107-httpsLive https://sourcectl.com/keryx, /privacy, /terms, /support, /review 200s (20 September 2026). Review is a placeholder (no QR). Czech HTML deferred #108. NAS evidence/keryx/2026-09-20-oa-107-https.txt (154 B). #107 already closed from the packet
OA-keryx-status-sidecarhetest2 (mnew.ssh) nginx /keryx-status/ + systemd; public health 200. NAS evidence/keryx/2026-09-19-oa-keryx-status-sidecar.txt (955 B, File Browser 19 September 2026). New QR after SafeCall upgrade remains
OA-123-review-hostLive /keryx/review, REVIEW-* ACL, off-LAN proof 20 September 2026. NAS 2026-09-20-oa-123-review-host.txt (205 B). #123 closed
OA-124-play-internal / testflightFirst Internal installs of 1.0.0+3 (10 September 2026). Soak stays #124
OA-125-listingsEN+CS listings, screenshots, App Privacy, Play Data safety in consoles 21 September 2026. NAS 2026-09-21-oa-125-listings.txt (568 B). #125 closed
OA-126-submitApple 1.0 submitted 21 September 2026; rejected 23 September 2026 (1.1 and 2.3.10). Play submission 1 was In review (18 (1.3.7), Czechia). NAS 2026-09-21-oa-126-submit.txt (159 B). Resubmit is OA-126-apple-resubmit. Keep #126 open
OA-launch-imageNavy megaphone launch image in 1.0.0+2

Session order ​

PhaseChaptersSplit here if needed
0NAS unlock — done 17 September 2026Skip
1OA-112-ci-enable doneSkip
2OA-132-intake-drill done; OA-129-hotfix-tabletop doneSkip
3OA-keryx-status-sidecar — done 19 September 2026Skip
4OA-121-app-walk done 19 September 2026; OA-116-device-a11y skipped 20 September 2026Skip
5OA-legal-cs done; OA-107-https done 20 September 2026Skip
6OA-123-review-host done 20 September 2026Skip
7OA-125-listings done 21 September 2026Skip
8OA-126-submit done 21 September 2026; Apple rejected 23 September 2026Skip
8bOA-126-apple-resubmitCurrent
9OA-119-ntfy-cutoverAfter public install + NSE (#165)
10OA-114-apple-recoveryAfter public launch

Mint the review ntfy ACL (first half of OA-123) any time after Phase 0. Do not tick OA-123 until the HTTPS page and off-LAN proof exist.

mermaid
flowchart TD
  prep[Unlock NAS]
  desk[GitLab runners]
  table[Intake drill plus hotfix tabletop]
  sidecar[OA-keryx-status-sidecar on hetest2]
  phones[OA-121 app walk]
  legal[Counsel legal drafts]
  https[Deploy public_base keryx pages]
  review[Review ACL QR off-LAN proof]
  listings[Screenshots and console paste]
  submit[Submit both stores for review]
  resubmit[Apple metadata resubmit same binary]
  cutover[deny-all only after public install NSE and ntfy app retired]
  apple[Apple recovery after public launch]
  prep --> desk --> table --> sidecar --> phones --> legal --> https --> review --> listings
  listings --> submit --> resubmit --> cutover --> apple

Ariadne / Theseus Internal tracks and the CEDR phone walk are not on this chart. See Ariadne close-out and Theseus close-out.


Phase 0 — Prep ​

Status: done 17 September 2026 (File Browser on GLaDOS, CT 500 192.168.178.213:8080). Skip this chapter. Next is OA-112-ci-enable (also done). Next remaining chapter is OA-legal-cs.

Goal: File Browser shows secrets/ and evidence/, not an empty tree.

Machines: Proxmox host or SSH to CT 500; then GLaDOS or MiniVan-3 on LAN.

Observed (do not re-create):

Path17 September 2026
secrets/keryx/Folders android, firebase, iOS, ntfy
evidence/keryx/2026-08-30-android-aab.txt, 2026-08-30-ios-ipa.txt, 2026-09-01-release-keryx-1.0.0+1.txt, 2026-09-13-store-org-eu-trader.txt
secrets/theseus/unlock.hash (97 B, 17 September 2026). Passphrase is not on the NAS
secrets/theseus/ops/token_label_notes.txt (17 September 2026). Token value is not in git

unlock.hash and ops notes are on the NAS (17 September 2026). Later release-evidence files (for example 1.2.0+7) may still be copied into evidence/keryx/; that is not Phase 0.

If File Browser is empty after a reboot, follow nas-unlock.md before continuing. Do not recreate secrets/ on the ciphertext path.

Verify

  • [x] File Browser lists existing Keryx secrets / evidence
  • [x] secrets/theseus/ exists (Theseus sitting is separate; see Theseus close-out)

Forbidden: Recreating secrets/ while the mount is locked; putting the gocryptfs passphrase in a unit file or this repo.


Phase 1 — Desk (no store consoles) ​

OA-112-ci-enable — Shared Linux runners ​

Status: done 17 September 2026. Skip this chapter. Next is Phase 2 (also done). Next remaining chapter is OA-legal-cs.

Log: Keryx operator actionsHow-to: ci.mdIssue: #112Machines: GitLab.com in a browser. Time box: 15 min + pipeline wait.

Gate: none. YAML is already in .gitlab-ci.yml.

  1. GitLab → Settings → CI/CD → Runners: shared Linux runners on for sourcecontrollers/safecall.
  2. Confirm a pipeline on master (or an MR) starts keryx:dart, keryx:server, and keryx:native-android.
  3. Wait until all three are green on the default branch.

Verify

  • [x] Shared runners enabled
  • [x] Three jobs green on master (pipeline 2858894786, commit 5c367031)
  • [x] No KERYX_KEY_*, keystores, or .p8 in CI variables

Evidence: GitLab pipeline URL (no tokens). Tick log: OA-112-ci-enable → done. GitLab: Reopened 17 September 2026 (was marked Done with remaining ACs open). Secret-free note posted. Do not close #112. Signed compile, SBOM, Swift / macOS, and privacy-manifest CI remain.

Forbidden: Registering GLaDOS as a runner; uploading store binaries from CI.


Phase 2 — Tabletops (no live halt) ​

OA-132-intake-drill ​

Status: done 17 September 2026. Skip this chapter. Next is OA-129-hotfix-tabletop.

Log: Keryx operator actionsHow-to: monitoring-intake.mdIssue: #132Machines: SafeCall support channel + NAS. Time box: 30 min.

Gate: none. This is not a production outage.

  1. Draft ticket A (allowed): platform + OS class, Keryx version+build, time window with timezone, friendly category label (not topic id), paused yes/no, camera/notification granted yes/no. Fictional site only.
  2. Draft ticket B (forbidden example): a QR photograph or a tk_… in the body. Mark it must not be filed. Practice: do not paste it into GitLab or chat; say “rotated” on NAS if a real secret ever arrives.
  3. Confirm the same-business-day ack path for a Sev1 core-path class reaches Thomas (P0-05). Write that path on the NAS note (channel name, not mailbox contents).
  4. Archive pass/fail on NAS evidence/keryx/ (suggested YYYY-MM-DD-oa-132-intake-drill.txt). No secrets.

Verify

  • [x] Redacted ticket shape matches the intake table
  • [x] Forbidden example was not filed
  • [x] Ack owner named as Thomas; no new SDK or status page

Evidence: NAS evidence/keryx/2026-09-17-oa-132-intake-drill.txt (1.05 KiB, File Browser 17 September 2026). Do not copy ticket bodies into git. Tick log: OA-132-intake-drill → done. GitLab: Secret-free note posted 17 September 2026. Drill AC ticked on the work item. Do not close #132.

Forbidden: Analytics SDK, Crashlytics, public status page, copying production alert bodies into git.


OA-129-hotfix-tabletop ​

Status: done 17 September 2026. Skip this chapter. Next remaining chapter is OA-legal-cs.

Log: Keryx operator actionsHow-to: hotfix-runbook.mdIssue: #129Machines: Desk + NAS. Time box: 40 min.

Gate: none. Not a live Play / ASC halt.

  1. Pick one fictional Sev1: credential leak or store stop.
  2. Walk, out loud or in the NAS note: halt staged Play rollout vs pause App Store phased release vs Czech unpublish vs superseding higher build. Record that already-installed users keep the bad build.
  3. Draft secret-free GitLab wording (symptoms, version/build class, decision). Include a forbidden example (paste tk_… or a QR photo) marked do not send.
  4. Archive pass/fail on NAS evidence/keryx/ (suggested YYYY-MM-DD-oa-129-hotfix-tabletop.txt).

Verify

  • [x] Halt vs superseding build vs unpublish written
  • [x] No-downgrade limit written
  • [x] Forbidden example not filed in GitLab
  • [x] Did not click halt / unpublish on the real listing

Evidence: NAS evidence/keryx/2026-09-17-oa-129-hotfix-tabletop.txt (644 B, File Browser 17 September 2026). Do not copy the note into git. Tick log: OA-129-hotfix-tabletop → done. GitLab: Secret-free note posted 17 September 2026. Tabletop AC ticked on the work item. Do not start #128. Do not close #129.

Forbidden: Live console halt; starting the monthly train (#128); unpublishing Keryx.


Phase 3 — Notify-host sidecar ​

Who: Operator on hetest2 (SSH mnew.ssh) + GLaDOS. Agent ticks from secret-free paste.

OA-keryx-status-sidecar ​

Status: done 19 September 2026. Skip this chapter. Next remaining chapter is OA-legal-cs.

Log: Keryx operator actionsHow-to: keryx-status, nginx snippet in templates/nginx-ntfy.confIssue: none (daily status plane). Do not close #119. Machines: hetest2 / https://notify.wantok.cz. Time box: 30 min.

Gate: ntfy already running on this host (listen-http 127.0.0.1:2586). Do not set auth-default-access: deny-all. Do not restart ntfy unless nginx -t fails and you caused it. Do not put KERYX_STATUS_READ_SECRET or tk_… in git or this chat.

Leave KERYX_STATUS_READ_SECRET empty for this sitting. Phone GET uses the QR subscribe token against sibling ntfy. HMAC is later, on a shared host that needs it.

This sitting does not require a new Keryx QR. Re-scan after SafeCall on the install is upgraded and Mobile Access mints status_url.

Paste each step in this Cursor chat. Crop passwords.

  1. SSH mnew.ssh (machine hostname ihetest2). Create the directory:

    bash
    mkdir -p /home/thomas/keryx-status
    chown thomas:thomas /home/thomas/keryx-status
    ls -ld /home/thomas/keryx-status

    Paste: that ls -ld line.

  2. Write /home/thomas/keryx-status/keryx-status.env with only:

    bash
    KERYX_STATUS_PORT=8792
    KERYX_STATUS_NTFY_URL=http://127.0.0.1:2586
    KERYX_STATUS_DB_PATH=/home/thomas/keryx-status/keryx-status.db
    KERYX_STATUS_MAX_BODY_BYTES=2000000

    No READ_SECRET line, or leave it commented. chmod 600 the file. Paste: grep -E '^[A-Z_]+=' /home/thomas/keryx-status/keryx-status.env | cut -d= -f1 (names only).

  3. Write /etc/systemd/system/keryx-status.service from keryx-status.md §3. Then:

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable keryx-status.service

    Do not start until the binary exists (step 6). Paste: systemctl is-enabled keryx-status.service (enabled).

  4. Sudoers drop-in /etc/sudoers.d/keryx-status (mode 440):

    thomas ALL=(root) NOPASSWD: /bin/systemctl restart keryx-status.service

    sudo visudo -cf /etc/sudoers.d/keryx-statusPaste: visudo OK line + sudo -n /bin/systemctl restart keryx-status.service; echo exit:$? (restart may fail until the binary exists; exit:0 after step 6 is the real proof. Here, paste that visudo is valid.)

  5. Edit the live notify.wantok.cz nginx server { (do not replace the whole file with the template). Add this inside the existing 443 server, before location /:

    nginx
    location /keryx-status/ {
        proxy_pass http://127.0.0.1:8792/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 2m;
    }

    Then sudo nginx -t && sudo systemctl reload nginx. Paste: nginx -t success line.

  6. On GLaDOS, from the safecall repo (SSH keys for mnew.ssh loaded):

    bash
    ./scripts/build/keryx-status.sh

    Paste: the last two lines (Built … and keryx-status deployed and keryx-status.service restarted.).

  7. From GLaDOS or hetest2:

    bash
    ssh mnew.ssh 'systemctl is-active keryx-status.service; curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8792/health'
    curl -sS -o /dev/null -w "%{http_code}\n" https://notify.wantok.cz/keryx-status/health
    curl -sS -o /dev/null -w "%{http_code}\n" https://notify.wantok.cz/keryx-status/v1/sites/TST000/status
    curl -sS -o /dev/null -w "%{http_code}\n" https://notify.wantok.cz/v1/health

    Expect: active, 200, public health 200, unauth status 401, ntfy health 200 (ntfy still on /). Paste: those five lines (status codes only). No Authorization headers.

  8. NAS evidence/keryx/YYYY-MM-DD-oa-keryx-status-sidecar.txt: keryx-status.service active; /keryx-status/health 200; unauth GET 401; ntfy /v1/health 200; READ_SECRET unset. Paste: File Browser listing of that filename (not secrets).

Verify

  • [x] Directory /home/thomas/keryx-status owned by thomas
  • [x] Env file exists; no secret pasted in chat
  • [x] keryx-status.service enabled and active
  • [x] Passwordless sudo /bin/systemctl restart keryx-status.service
  • [x] Public https://notify.wantok.cz/keryx-status/health is 200
  • [x] Unauth GET status is 401
  • [x] ntfy https://notify.wantok.cz/v1/health is still 200
  • [x] Did not set deny-all; did not paste tk_…

Evidence: NAS evidence/keryx/2026-09-19-oa-keryx-status-sidecar.txt (955 B, File Browser 19 September 2026). keryx-status.service active; local and public /keryx-status/health 200; unauth GET 401; ntfy /v1/health 200; READ_SECRET unset. Code on master 734a6b94. Tick log: OA-keryx-status-sidecar → done. GitLab: Secret-free notes posted 19 September 2026 on #51, #117, and #121. This row has no owning iid. Do not close those items.

Forbidden: Putting .env or READ_SECRET in git; replacing the whole nginx vhost so ntfy breaks; photographing a QR; claiming phones work before a new mint.


Phase 4 — Keryx phones (same devices) ​

Who: Operator on one iPhone + one Android (later OA-123). Agent: GitLab notes only.

OA-121-app-walk is done 19 September 2026. OA-116-device-a11y is skipped 20 September 2026 (#116 closed). Phase 4 is complete. Next is OA-legal-cs.

Use 1.2.1 (8)+ from TestFlight / Play Internal (this walk used 1.3.7 (18)). Installed 1.0.0+3 cannot receive the closed-app wake. English or Czech. One SafeCall administrator QR from Mobile Access (not Ariadne, not Theseus).

OA-121-app-walk ​

Status: done 19 September 2026. Skip this chapter. Next remaining chapter is OA-legal-cs.

Log: Keryx operator actionsHow-to: app-onboarding-guide.md (§2 install, §3 permissions, §4 scan, §5 first alerts, §6 day-to-day) Issue: #121Machines: One administrator phone + SafeCall Mobile Access. Time box: 30 min.

Gate: none. The #120 walk was install+scan only and does not close this. Mint a new Mobile Access QR after the site SafeCall includes 734a6b94 (SOS, watches, daily status / status_url). Old QRs will not GET Overview.

Paste each step in this Cursor chat. Cover any QR pixels.

  1. Czech App Store or Play Internal: search Keryx for SafeCall. Install 1.2.1 (8)+. Not 1.0.0+3. Not a sideload APK. Paste: TestFlight or Play showing Keryx for SafeCall installed, version visible.
  2. Open Keryx. You should see No notifications have been enabled yet and Scan QR code. Paste: that empty onboarding screen.
  3. Grant Camera and Notifications. If you already denied them:
    • iPhone: Settings → Keryx → Camera / Notifications → on
    • Android: Settings → Apps → Keryx → Permissions / Notifications → on Then return to Keryx. Paste: Keryx after both permissions are on (still no QR in the photo).
  4. On the customer SafeCall box (not the lab host unless that is the walk site): open Tools → Mobile Access. Use the Keryx QR, not Ariadne, not Theseus. On the phone tap Scan QR code. Point the camera at the live monitor. Do not photograph the QR. Paste: Keryx Active after a successful scan (empty list is OK).
  5. On Mobile Access, leave Notification pipeline tests selected. Tap Send test notification. Do not use Watch/Panic Test Send. Paste: Active (or a banner) showing the test item. Crop site names if needed.
  6. Open Archive. Toggle Pause notifications, then Resume. Config must still be there. Paste: Pause state, then Active after Resume.
  7. Gear → Language. Switch once and switch back. Do not uninstall the official ntfy app. Do not set auth-default-access: deny-all. Paste: Language screen.

Verify

  • [x] Store/Internal install → permissions → Scan QR → Active
  • [x] Test notification appeared (Active and/or banner)
  • [x] Pause does not drop config
  • [x] No QR photo in chat or GitLab

Evidence: NAS evidence/keryx/2026-09-19-oa-121-app-walk.txt (32 B, File Browser 19 September 2026). TestFlight Keryx for SafeCall 1.3.7 (18) on iPhone. Empty onboarding → Notifications + Camera allowed → Overview after scan (sensor all-clear 19 September 2026 18:57; SOS and watch no recent events). Mobile Access pipeline test: lock-screen banner plus detail Dashboard ntfy recheck / SafeCall CDR001 notification pipeline test (CDR001-test). Settings Pause then Resume (config remained). Language switched to Čeština. No QR photographed. Tick log: OA-121-app-walk → done. GitLab: Secret-free note posted 19 September 2026. Do not close #121 (live web #107, Czech #108, screenshots #125 remain).

Forbidden: Sideload; official ntfy uninstall as part of this walk; deny-all.


OA-116-device-a11y ​

Status: skipped 20 September 2026. Do not run VoiceOver / TalkBack. #116 is closed. Next remaining chapter is OA-legal-cs.

Log: Keryx operator actionsHow-to: accessibility.mdIssue: #116 (closed 20 September 2026)

Keryx is for named hospital security personnel and SafeCall administrators, not a general-public accessibility store claim. In-repo camera/notification Open Settings recovery and widget tests stay. We do not claim VoiceOver, TalkBack, or WCAG 2.2 AA. Physical AT / contrast / tablet / orientation evidence is accepted out of scope for launch. #117 (OEM / soak) is unchanged.

Verify

  • [x] VoiceOver / TalkBack device walk skipped (trained operators)
  • [x] No WCAG 2.2 AA or AT conformance claim
  • [x] #116 closed 20 September 2026 (secret-free note posted)

Evidence: Decision recorded here and on #116. No NAS VoiceOver file. Tick log: OA-116-device-a11y → done (skipped). GitLab: #116 closed 20 September 2026.

Forbidden: Claiming a WCAG conformance badge; reopening #116 as a launch blocker without a new product decision.


Status: done 20 September 2026 (OA-legal-cs and OA-107-https). Next is Phase 6.

Who: Operator (counsel + DNS/TLS host). Agent may rsync public HTML after {public_base} is known outside git.

Log: Keryx operator actionsHow-to: legal/Issue: #108Status: done 20 September 2026. Operator confirmed counsel reviewed the EN+CS legal package. Letter not in git. English public HTML DRAFT banners removed the same day.

Gate: none to send. Do not strip DRAFT banners in git until sign-off exists.

  1. Attach the current files under docs/gtm/keryx/legal/ (install, privacy, terms, support — EN + CS). Send them on the approved counsel path. Do not invent {support_email} in git.
  2. When counsel replies: record sign-off location only (NAS folder or mailbox name). Do not commit the letter.
  3. After sign-off: strip DRAFT banners from English public HTML and update legal/ status. Czech public HTML stays on #108.

Verify

  • [x] Counsel received the current drafts
  • [x] Sign-off recorded (letter not in git)
  • [x] DRAFT banners removed from English /keryx/privacy, /keryx/terms, /keryx/support after sign-off (20 September 2026)

Evidence: Operator confirmation 20 September 2026. Letter not in git. Tick log: OA-legal-cs → done. GitLab: #108 also owns Czech app UI / handbook. Do not close #108 from counsel review alone.

Forbidden: Stripping DRAFT in git without sign-off; inventing mailboxes.


OA-107-https — Live {public_base}/keryx/* ​

Status: done 20 September 2026. Skip this chapter. Next is OA-123-review-host.

Log: Keryx operator actionsHow-to: public-web-pages.mdIssue: #107Machines: DNS/TLS host for {public_base} + NAS. Time box: hours (DNS).

Gate: {public_base} is https://sourcectl.com (operator record 20 September 2026 in public-web-pages.md). Pages are implemented in the live Bun + Elysia app (diametheus/website), not SafeCall VitePress and not the lab host. Do not reuse https://safecall-lab.sourcectl.com as the Keryx store privacy URL.

  1. Host option C (Bun Source Control app) is recorded. NAS note can confirm the same host; do not switch to VitePress or the retired Astro repo. Paste: that NAS note when you deploy.
  2. Publish these five paths over HTTPS, no login:
    • {public_base}/keryx
    • {public_base}/keryx/privacy
    • {public_base}/keryx/terms
    • {public_base}/keryx/support
    • {public_base}/keryx/review (empty placeholder is OK until OA-123)
  3. Legal HTML is copied from legal/. DRAFT banners were removed 20 September 2026 after OA-legal-cs. Do not invent a mailbox/phone.
  4. curl -I each path. Expect 200 and HTTPS. HTTP must redirect. Paste: the five curl -I status lines (URLs may be cropped to path-only).
  5. Czech public HTML: publish or write a #108 deferral on NAS. Paste: browser tab of /keryx/privacy with sourcectl as publisher. Not the lab host.

Verify

  • [x] Four legal/install paths return 200 over HTTPS without login
  • [x] /keryx/review exists (QR image still OA-123)
  • [x] HTTP redirects to HTTPS (308)
  • [x] Privacy URL is not https://safecall-lab.sourcectl.com/…
  • [x] No invented mailbox/phone in git

Evidence: NAS evidence/keryx/2026-09-20-oa-107-https.txt (154 B, File Browser 20 September 2026). Browser tab of /keryx/privacy shows Publisher: Source Control. /keryx/review is a secret-free placeholder (no QR, no send-test). Czech public HTML deferred to #108. Tick log: OA-107-https → done. GitLab: #107 already closed from the publication packet. Secret-free note posted 20 September 2026. In-app About links and store URL paste stay OA-125. Do not close #108.

Forbidden: Dead privacy URL in a store console; BleuVista as Keryx owner; consumer lead forms on Keryx pages; treating the lab host as {public_base}.


Phase 6 — Reviewer environment ​

Who: Operator (hetest2 ACL + off-LAN phones). Agent: GitLab notes only.

OA-123-review-host ​

Log: Keryx operator actionsHow-to: reviewer-environment.mdIssue: #123Machines: hetest2 + {public_base} + one iPhone + one Android off LAN. Time box: 1–2 h after HTTPS exists.

Status: done 20 September 2026 (page + six-topic ACL including REVIEW-status + off-LAN both OS + NAS + Overview all-clear). Do not set auth-default-access: deny-all. Do not paste listing copy. Do not close #123.

Gate: green. {public_base}/keryx/review is public HTTPS 200 (OA-107 placeholder).

A — ACL (done 20 September 2026)

Observed on hetest2 (ihetest2) + Apple Passwords (do not re-create):

Check20 September 2026
Userskeryx-review-sub and keryx-review-pub (role: user, tier: none)
Sub ACLread-only on REVIEW-panic, REVIEW-battery, REVIEW-sensor, REVIEW-unseen, REVIEW-health, REVIEW-status
Pub ACLread-write on the same six topics
Not usedTST000 topics; safecall-publisher / safecall-ops are not on the review QR
TokensLabels keryx-review-sub and keryx-review-pub; values live in Apple Passwords (NTFY entries, website notify.wantok.cz). Not in git
NAS notessecrets/keryx/ntfy/keryx-review-users.txt (192 B, File Browser 20 September 2026). Dual-run file 2026-09-13-ntfy-dual-run-notes.txt unchanged
Dual-runuser * still has read-write to other topics. Did not set deny-all
  1. [x] Dedicated review users + REVIEW-* ACL + labeled tokens on hetest2.
  2. [x] Tokens in Apple Passwords (usernames keryx-review-sub / keryx-review-pub). sudo ntfy user list showed both users and the five topics (no token values in the list). NAS secrets/keryx/ntfy/keryx-review-users.txt (192 B, File Browser 20 September 2026).
  3. [x] Live safecall.keryx.ntfy.v2 JSON off-git on GLaDOS $HOME/sourcectl/keryx-review/keryx-review-qr.json (686 B, 20 September 2026). Type v2, debug_access false, five REVIEW-* topics, status_url set, subscribe_auth Bearer tk_… (not tk_local_…). Not in the safecall repo. Payload not pasted.
  4. [x] QR PNG on NAS evidence/keryx/2026-09-20-keryx-review-qr.png (17.66 KiB, File Browser 20 September 2026). Image not pasted into chat.
  5. [x] Overview ACL (20 September 2026, ihetest2): keryx-review-sub read-only and keryx-review-pub read-write on REVIEW-status. Existing five REVIEW-* grants unchanged. No tokens in the paste. Did not set deny-all.

B — Page + Send-test

  1. [x] PNG copied to GLaDOS gitignored diametheus/website/static/keryx/assets/review-qr.png (18 084 B, check-ignore 20 September 2026). Production website .env has KERYX_REVIEW_NTFY_TOKEN (names-only grep; value not pasted).
  2. [x] Live {public_base}/keryx/review 200; QR asset 200 (18 084 B); HTML has Send-test POST and no tk_…. Server-side POST returns 303 to ?sent=1 (A1 Panic button on REVIEW-panic; best-effort keryx-status PUT). Token not in page source. A5 health does not appear on Active. Browser tab 20 September 2026: publisher Source Control, Send-test visible, QR covered (not pasted in the clear).

C — Off-LAN proof

  1. Use cellular or a non-office network. Install Keryx from TestFlight / Play Internal.
  2. Open {public_base}/keryx/review → camera + notifications → scan the live QR → tap Send test.
  3. Active shows the sample. Archive works. Pause keeps config. Repeat on the other OS. Paste: Active on iPhone (done) and Active on Android after Send-test. Cover the QR. No tokens. Overview may still say Waiting for status until REVIEW-status ACL exists and Send-test has PUT a snapshot.
  4. [x] NAS pass/fail note. No QR photo in GitLab. File Browser 20 September 2026: evidence/keryx/2026-09-20-oa-123-review-host.txt (205 B). QR PNG listed beside it (covered in the paste).

iPhone (20 September 2026, 5G): Active shows two Panic button alerts rows (Demo panic button pressed at Demo Site North). Details: legacy plain-text body (expected; Send-test is not an envelope), received 2026-09-20T13:56:06. Archive / Delete present. QR not in the paste.

Android (20 September 2026): first paste was 1.3.6 (17) (Overview health-only). Operator then updated Play Internal; Android Overview now matches iPhone 1.3.7 (18) (operator confirmed 20 September 2026). Active A1 panic pass on both OS. Review topics REVIEW-panic / REVIEW-battery / REVIEW-sensor / REVIEW-unseen still do not match fromTopic (-sos, -batteries, -sensors, -notseen); only REVIEW-health maps. Scan replaces the QR config and unsubscribes ntfy; it does not clear a cached status snapshot. Reset during an in-flight subscribe can need a second tap.

Overview (20 September 2026, after REVIEW-status + Send-test PUT): All clear as of 9/20/2026 2:23 PM on Sensor conditions, Device batteries, and Devices not seen. Waiting for status is gone.

Verify

  • [x] Topics are REVIEW-*, not TST000 (user list 20 September 2026)
  • [x] upstream-base-url is not https://ntfy.sh (OA-119-ntfy-apns: empty)
  • [x] Off-LAN iPhone scan + Send-test pass (20 September 2026, 5G, A1)
  • [x] Off-LAN Android scan + Send-test pass (20 September 2026, A1 Active)
  • [x] Same Keryx version on both phones (1.3.7 (18), 20 September 2026)
  • [x] Publish token absent from page source (curl 20 September 2026)
  • [x] Did not apply deny-all; did not paste store listings
  • [x] NAS evidence/keryx/2026-09-20-oa-123-review-host.txt (205 B, File Browser)

Evidence: NAS evidence/keryx/2026-09-20-oa-123-review-host.txt (205 B, File Browser 20 September 2026). QR PNG may sit beside it on NAS only. Tick log: OA-123-review-host → done (20 September 2026). GitLab: #123 closed. Listing paste was OA-125 (done). Submit is #126.

Forbidden: debug_access: true; production building names; deny-all; committing the QR PNG; listing-copy paste.


Phase 7 — Store listings (paste only) ​

Who: Operator in ASC + Play Console. Agent: GitLab notes only. Do not set deny-all. Do not paste Keryx listing copy onto Ariadne or Theseus.

OA-125-listings ​

Log: Keryx operator actionsHow-to: store-listing-copy.md, store-screenshot-kit.md, apple-privacy-compliance.md, play-data-safety.mdIssue: #125Machines: Capture devices + ASC + Play Console. Time box: half day.

Gate (all required):

  • [x] OA-107: privacy/terms/support/install return 200
  • [x] OA-123: off-LAN Send-test + scan passed
  • [x] Pasted into Internal / listing draft (21 September 2026). Public submit is OA-126-submit

Stop if the privacy URL would be dead.

Do this only for Keryx for SafeCall. Never paste this copy onto Ariadne or Theseus.

  1. Capture frames 1–6 from store-screenshot-kit.md on the reviewer environment. Privacy-safe catalog only. Paste: the six store frames (no QR, no tokens).

    iPhone TestFlight 1.3.7 (18), English UI (Czech chrome stays #108):

    • [x] Frame 1 unconfigured onboarding — empty state, Scan QR code, no QR/tokens (20 September 2026 14:59)
    • [x] Frame 2 QR scan chrome — empty viewfinder, SafeCall Mobile Access help, no QR/tokens (recapture 20 September 2026 15:01, no AirPods banner)
    • [x] Frame 3 Active tab — Panic button alerts, Demo Site, Active selected (20 September 2026 15:03). Recapture before console upload: dismiss the OS notification banner
    • [x] Frame 4 Archive tab — archived Panic button alerts, Demo Site, Archive selected (20 September 2026 15:04). No QR/tokens. Optional recapture before upload: mix categories A1–A4 instead of panic-only
    • [x] Frame 5 Notification detail — Demo Site North body, received time, Delete (20 September 2026 15:06). No JSON/token. Optional recapture: friendlier time; “Legacy notification” is acceptable
    • [x] Frame 6 Settings / Advanced — Pause notifications + Scan new QR code + Reset App, version 1.3.7 (18) (20 September 2026 15:07–15:08). No transport/topic/debug. Delivery log not opened.
  2. Czech UI: #108 in-app chrome or a written #108 deferral on NAS.

    • [x] NAS evidence/keryx/2026-09-20-oa-125-108-deferral.txt (399 B) written, then superseded this sitting: operator will paste CS listing copy and capture CS frames via in-app Čeština (Keryx already ships app_cs.arb). Do not close #108 (public CS HTML and remaining linguistic QA stay).
    • [x] Czech App Store name + subtitle on App Information (Keryx pro SafeCall / Doprovod pro správce SafeCall), 20 September 2026
    • [x] Czech version page 1.0 Prepare for Submission: promo, description (CS char count matches packet), keywords, Support + Marketing URLs, copyright (20 September 2026). No What’s New on first version 1.0 (expected). 0 screenshots. Do not click Add for Review.
    • [x] English version page 1.0: promo, description (EN char count matches packet), keywords, Support + Marketing URLs, copyright (20 September 2026). Do not click Add for Review.
    • [x] App Review Information: Sign-In not required; Notes include commercial/QR/safety block and https://sourcectl.com/keryx/review (20 September 2026). Contact values stay in ASC / Apple Passwords, not git. Add for Review remains inactive.
    • [x] Content Rights: No third-party content (20 September 2026).
    • [x] Age Ratings: 4+ (172 countries); Brazil AL; Korea ALL; Vietnam 00+; earlier-than-26 also 4+ (20 September 2026). Not Kids. No override.
    • [x] App Encryption Documentation: no file uploaded (20 September 2026). HTTPS / Apple OS TLS only; the +/Upload wizard is non-exempt docs and stays unused. Source now sets ITSAppUsesNonExemptEncryption = false in keryx/ios/Runner/Info.plist; takes effect on the next signed IPA (current TestFlight 1.3.7 does not include the key).
    • [x] App Privacy nutrition Published (20 September 2026): Other User Content + Device ID + Other Data; App Functionality; linked; not tracking. Privacy URL https://sourcectl.com/keryx/privacy. User Privacy Choices empty (no ATT). Do not click Add for Review.
    • [x] Czech Frame 1 — empty onboarding, Naskenovat QR kód, title Keryx pro SafeCall (20 September 2026 16:18). No QR/tokens.
    • [x] Czech Frame 2 — empty viewfinder, Naskenovat QR kód, Mobilní přístup hint (20 September 2026 16:35). No QR/tokens.
    • [x] Czech Frame 3 — Aktivní, Poplachové tlačítko, Demo lokality Sever (20 September 2026 16:41). No QR/tokens. No OS banner.
    • [x] Czech Frame 4 — Archiv, Poplachové tlačítko, Demo lokality Sever (20 September 2026 16:41). No QR/tokens.
    • [x] Czech Frame 5 — Podrobnosti upozornění, Demo lokality Sever, Smazat (20 September 2026 16:42). No JSON/token.
    • [x] Czech Frame 6 — Pozastavit upozornění + Naskenovat nový QR kód + Resetovat aplikaci, Čeština, 1.3.7 (18) (20 September 2026 16:43). Delivery log not opened.
    • [x] Upload iPhone frames to ASC 1.0 (21 September 2026): version 1.0 Prepare for Submission, iPhone 6.5" Display well Using 6.9" Display, 8 of 10 in English (U.S.) and Czech. Files from keryx/store-assets/screenshots/asc-iphone-6.9-1260x2736/ (not 472×1024 chat copies). EN Frame 3 recapture (no OS banner) is in the set. Add for Review not clicked.
    • [x] Reorder EN + CS iPhone wells (21 September 2026, Media Manager): 01 onboarding, 02 scan, 03 active, 04 archive, 05 detail, 06a pause, 06b advanced, overview last. 6.5" Using 6.9" Display. Do not click Add for Review.
    • [ ] iPad Pro 13" slots. Well confirmed empty (21 September 2026): iPad 13" Display, portrait 2064 × 2752. Do not upload iPhone 1260×2736 files.
      • [x] iPad EN Frame 1 onboarding — Keryx for SafeCall, Scan QR code, no QR/tokens (21 September 2026, Simulator iPad Pro 13-inch M4, 2064×2752)
      • [x] iPad EN Frame 2 scanner — Scan QR code, empty viewfinder, Mobile Access hint, no QR/tokens (21 September 2026)
      • [x] iPad EN Frame 3 Active — Active, Panic button alerts, Demo Site North, no OS banner, no QR/tokens (21 September 2026)
      • [x] iPad EN Frame 4 Archive — Archive, Panic button alerts, Demo Site North, no QR/tokens (21 September 2026)
      • [x] iPad EN Frame 5 detail — Notification details, Demo Site North, Delete, no JSON/token (21 September 2026)
      • [x] iPad EN Frame 6 Settings — pause on, Scan new QR code, Reset App, 1.3.7 (18), both 06a/06b fit one 13" frame (21 September 2026). Delivery log not opened.
      • [x] iPad EN Overview extra — SafeCall status, All clear cards, Overview selected (21 September 2026)
      • [x] iPad CS Frame 1 onboarding — Keryx pro SafeCall, Naskenovat QR kód, empty state (21 September 2026)
      • [x] iPad CS Frame 2 scanner — Naskenovat QR kód, empty viewfinder, Mobilní přístup hint, no QR/tokens (21 September 2026)
      • [x] Upload EN+CS iPad 13" wells (21 September 2026): Media Manager iPad 13" Display, 7 of 10 each locale (no duplicate 06b). Order: onboarding, scan, Active, Archive, detail, Settings (one frame), Overview last. First 3 are install-sheet order. 11" / 12.9" empty (kit requires 13" only). Do not click Add for Review.
      • [x] iPad CS Frame 6 Settings — Nastavení, Pozastavit upozornění on, Naskenovat nový QR kód, Resetovat aplikaci, Čeština, 1.3.7 (18) (21 September 2026)
      • [x] iPad CS Overview extra — Přehled, Stav SafeCall, Vše v pořádku (21 September 2026)
      • [x] iPad CS Frame 3 Active — Aktivní, Poplachové tlačítko, Demo lokality Sever, no OS banner (21 September 2026)
      • [x] iPad CS Frame 4 Archive — Archiv, Poplachové tlačítko, Demo lokality Sever (21 September 2026)
      • [x] iPad CS Frame 5 detail — Podrobnosti upozornění, Demo lokality Sever, Smazat (21 September 2026)
  3. App Store Connect → Apps → Keryx for SafeCall → version Prepare for Submission. Paste name, subtitle, promotional text, description, keywords, What’s New, reviewer notes from store-listing-copy.md. URLs = live {public_base}/keryx/…. App Privacy from apple-privacy-compliance.md. Upload screenshots. Do not click Submit for Review. Paste: ASC listing page (no Submit) and App Privacy summary.

  4. Play Console → Keryx for SafeCall → Grow users → Store presence → Main store listing (UI: Store listings → Default store listing). Same copy + screenshots. Policy → Data safety from play-data-safety.md. Internal testing reviewer instructions = {public_base}/keryx/review. Do not start Production. Paste: Play listing + Data safety. Production still Inactive.

    • [x] Play Default store listing opened (21 September 2026): language Default – English (United States) – en-US. App name Keryx for SafeCall (18/30) already correct. Short / full description empty. Icon, feature graphic, and phone screenshots empty. Do not use Import translations with AI. Do not start Production.
    • [x] Paste EN short + full description, Save (21 September 2026): App name 18/30, short 79/80, full 2928/4000, footer Publisher sourcectl / Category Business / Price Free.
    • [x] Upload Play EN icon 512, feature graphic 1024×500, phone 9:16 screenshots (21 September 2026): 7/8, kit order onboarding → scan → Active → Archive → detail → Settings → Overview. Feature graphic title Keryx for SafeCall. Do not start Production.
    • [x] Add Play listing language Czech. Paste CS name, short, full description; CS feature graphic + phone 9:16 shots. Save (21 September 2026): Czech – cs-CZ, name 18/30, short 78/80, full 2806/4000, feature graphic Keryx pro SafeCall, 7/8 phone shots in kit order. Do not start Production.
    • [x] Play Store settings (21 September 2026): dashboard Select an app category and provide contact details is complete (with store listing). Do not start Production.
    • [x] Play App content → Privacy policy (21 September 2026): Actioned, URL https://sourcectl.com/keryx/privacy. Need attention still 9 (Ads, Sign in details, Content ratings, …). Do not start Production.
    • [x] Play App content → Ads (21 September 2026): Actioned. Need attention 8. Do not start Production.
    • [x] Play App content → Sign in details (21 September 2026): Restricted Yes; instructions include https://sourcectl.com/keryx/review; no username/password. Actioned. Need attention 7. Do not start Production.
    • [x] Play App content → Content ratings (21 September 2026): IARC Completed. Lowest/Everyone-class icons (ESRB E, PEGI 3, USK 0, IARC 3+). Certificate ID still blank. Do not start Production.
    • [x] Play App content → Target audience (21 September 2026): 18 and over only; optional minor-block left off. Actioned. Do not start Production.
    • [x] Play App content → Data safety (21 September 2026): saved. Device or other IDs collected + shared for App functionality; encrypted in transit; delete + privacy https://sourcectl.com/keryx/privacy. Dashboard 8 of 11. Do not start Production.
    • [x] Play Government apps + Financial features (21 September 2026): Publishing overview “What you’ve told us” shows both updated. Send app for review stays locked. Do not start Production or Closed testing.
    • [x] Play Health (21 September 2026): operator confirmed complete. Publishing overview still lists Health among unsubmitted drafts — do not Send app for review. Do not start Production.
    • [x] Play Internal testing (21 September 2026): Testers has no instructions field. Review URL already in Sign-in details. Track Active, latest 18 (1.3.7), not reviewed. Did not Create new release. Did not Promote release. Do not start Production.
  5. [x] NAS evidence/keryx/2026-09-21-oa-125-listings.txt (568 B, File Browser 21 September 2026). Secret-free; no Production; no Submit.

Verify

  • [x] EN + CS listing fields pasted (21 September 2026)
  • [x] Privacy URL 200 (not the lab host unless NAS records a later decision)
  • [x] Reviewer URL is the live review page
  • [x] Pasted Internal / listing draft only (21 September 2026). Submit is OA-126-submit

Evidence: NAS evidence/keryx/YYYY-MM-DD-oa-125-listings.txt. Tick log: OA-125-listings → done. GitLab: Close #125 (listings/forms in consoles). Submit is #126. Soak (#124) and OEM matrix (#117) stay open.

Forbidden: Inventing contacts; real client QR in screenshots; pasting this copy onto Ariadne / Theseus. Submit is OA-126-submit.


Phase 8 — Store submit (before ntfy cutover) ​

Who: Operator on App Store Connect and Play Console. Agent: GitLab notes.

OA-126-submit ​

Log: Keryx operator actionsHow-to: store-listing-copy.md, play-data-safety.md, Publishing KeryxIssue: #126Machines: GLaDOS + ASC + Play Console.

Decision (21 September 2026): send both stores for review now so clients can install Keryx and replace the official ntfy app. Apply auth-default-access: deny-all only in OA-119-ntfy-cutover (#166) after the app is publicly installable in Czechia, #165 NSE is shipped, and official ntfy clients are retired.

Gate — all must be true or STOP:

  • [x] OA-125-listings done (21 September 2026)
  • [x] Reviewer URL https://sourcectl.com/keryx/review returns 200
  • [x] Privacy URL https://sourcectl.com/keryx/privacy returns 200
  • [x] Dual-run still in place (auth-default-access is not deny-all)
  1. App Store Connect → Apps → Keryx for SafeCall → the version that already has EN+CS listing, screenshots, and review notes. Confirm notes still include https://sourcectl.com/keryx/review. Add for Review / Submit for Review. Do not file expedited review. Paste: Waiting for Review (or equivalent). No QR. Done 21 September 2026: version 1.0 Waiting for Review. Do not remove this version from review.
  2. Play Console → Test and release → Production. Country Czechia only. Create or promote a Production release of the same Internal candidate 18 (1.3.7) so Google has a public binary. Then Publishing overview → Send app for review. Paste: sent / in-review confirmation. Do not apply deny-all. Done 21 September 2026: Play Submission activity ID 1, 2:45 PM, Production + Store Listing + App Content + Store settings, status In review. Czechia only; 18 (1.3.7) full rollout after approval. Do not apply deny-all.
  3. NAS note: both stores in review; “no deny-all”. Paste: File Browser row for evidence/keryx/YYYY-MM-DD-oa-126-submit.txt. Done 21 September 2026: evidence/keryx/2026-09-21-oa-126-submit.txt (159 B, File Browser).

Verify

  • [x] Apple version is in review (1.0 Waiting for Review, 21 September 2026)
  • [x] Play changes / Production candidate are in review (submission 1, 21 September 2026 2:45 PM)
  • [x] Notify host still dual-run (not deny-all; not applied this sitting)
  • [x] Reviewer page still 200 (https://sourcectl.com/keryx/review, 21 September 2026)

Evidence: NAS evidence/keryx/2026-09-21-oa-126-submit.txt (159 B). Tick log: OA-126-submit → done (submitted 21 September 2026; not approved). GitLab: Notes on #126. Keep #126 open until both stores approve. Public comms / staged rollout remain #127.

Forbidden: deny-all; unpublish; expedited review as a tabletop; pasting this onto Ariadne / Theseus.

Apple rejected this submission on 23 September 2026. The next chapter is OA-126-apple-resubmit. Do not treat the 21 September “Waiting for Review” paste as the current state.


Phase 8b — Apple metadata resubmit ​

Who: Operator on App Store Connect. Agent: GitLab notes.

OA-126-apple-resubmit ​

Log: Keryx operator actionsHow-to: store-listing-copy.md (Apple long descriptions and reviewer notes only), store-screenshot-kit.md sample A2Issue: #126Machines: Capture device or simulator + App Store Connect.

Gate — all must be true or STOP:

  • [ ] Rejected version is still 1.0 (18). Do not upload a new IPA.
  • [ ] Apple EN and CS descriptions in this repo are the Long description (Apple) blocks, not the Google blocks.
  • [ ] Dual-run still in place (auth-default-access is not deny-all)
  1. App Store Connect → Apps → Keryx for SafeCall → rejected version 1.0. English (U.S.) and Czech: replace the description with the matching Long description (Apple) from store-listing-copy.md. Do not paste the Google description. Do not add What’s New. Paste: both description editors after save (no QR).

  2. Replace review notes with the English reviewer template from that file. Safety posture must read “Not a medical device and not a dispatch system.” The setup line must end with “credential.” Keep https://sourcectl.com/keryx/review. Paste: the notes field (crop phone and email if shown).

  3. Screenshots are optional for this resubmit. Apple named the description. There is no low-battery PNG in the repo. Do not re-upload the files below; they are the panic frames already in App Store Connect.

    iPhone 6.9" (the well marked Using 6.9" Display):

    • keryx/store-assets/screenshots/asc-iphone-6.9-1260x2736/ios-en-03-active-1260x2736.png
    • keryx/store-assets/screenshots/asc-iphone-6.9-1260x2736/ios-en-04-archive-1260x2736.png
    • keryx/store-assets/screenshots/asc-iphone-6.9-1260x2736/ios-en-05-detail-1260x2736.png
    • same names with ios-cs- for Czech

    iPad 13":

    • keryx/store-assets/screenshots/ipad-en-03-active-2064x2752.png
    • keryx/store-assets/screenshots/ipad-en-04-archive-2064x2752.png
    • keryx/store-assets/screenshots/ipad-en-05-detail-2064x2752.png
    • same names with ipad-cs- for Czech

    Leave onboarding, scan, settings, and overview. The chat copies under keryx/store-assets/screenshots/oa-125-2026-09-20-chat-copies/ are 472×1024 and must not be uploaded. Play frames under play-phone-1080x1920/ stay on Play.

    https://sourcectl.com/keryx/review Send test publishes the panic sample only (REVIEW-panic). It does not produce a low-battery frame. Skip this step unless you capture new Active, Archive, and detail shots that show Low battery alerts / Slabá baterie instead. Do not block the description paste or the resubmit on that capture.

  4. If you can edit the live host, replace “is not an emergency-dispatch system” on https://sourcectl.com/keryx with “is not a dispatch system.” Do not block steps 1–2 on a site deploy. The page source is not in this repo.

  5. Resolution Center reply, then Resubmit to App Review on the same build 1.0 (18). Do not request expedited review.

    Paste this reply:

    text
    We updated the English (U.S.) and Czech descriptions. Android and Google Play references are removed; this submission is the iPhone and iPad app only. We also removed wording that could be read as medical treatment, an emergency service, or an adults-only product. Keryx shows supplemental operational alerts for administrators of an existing SafeCall installation. It does not create or host user content. The binary is unchanged: 1.0 (18).

    Paste: Waiting for Review (or equivalent) for 1.0 (18). No QR.

  6. NAS evidence/keryx/YYYY-MM-DD-oa-126-apple-resubmit.txt: rejection guidelines, “metadata only”, “same binary 1.0 (18)”, “no expedited review”. No secrets.

Verify

  • [ ] EN and CS Apple descriptions match the Apple blocks, not the Google blocks
  • [ ] Screenshot swap skipped, or new low-battery captures uploaded (the repo PNGs are the old panic frames)
  • [ ] Same build 1.0 (18) is back in review
  • [ ] Notify host still dual-run

Evidence: NAS evidence/keryx/YYYY-MM-DD-oa-126-apple-resubmit.txt. Tick log: OA-126-apple-resubmit → done when resubmitted, not when approved. GitLab: Note on #126. Keep #126 open until both stores approve.

Forbidden: a new IPA; pasting the Google description into App Store Connect; expedited review; deny-all; unpublishing Play; pasting this onto Ariadne / Theseus.


Phase 9 — ntfy deny-all cutover ​

Who: Operator on the notify host. Agent: GitLab notes only.

OA-119-ntfy-cutover ​

Log: Keryx operator actionsHow-to: ntfy-auth-and-play-internal.md, templates/ntfy-server.deny-all.yml, ntfy-fcm-apns.mdIssue: #166 (residual of closed #119).

Gate — all must be true or STOP:

  • [ ] Keryx is publicly installable in the Czech App Store and Google Play (not Internal-only). #126 approved; clients can download and replace the official ntfy app
  • [ ] Official / generic ntfy app clients are retired on every site that uses this notify host (OA-121 migration done site-wide, not one phone)
  • [ ] Keryx iOS Notification Service Extension is shipped (#165; generic poll_request “New message” APNs is not enough)
  • [ ] Dual-run anonymous publish is no longer required for Recheck probes you still care about

If NSE is missing in keryx/ios/, do not apply deny-all. iOS banners will regress to generic poll alerts.

When the gate is green:

  1. On the notify host, copy /etc/ntfy/server.yml to a backup file next to it (not git).
  2. Edit /etc/ntfy/server.yml. Change only:
    yaml
    auth-default-access: "deny-all"
    upstream-base-url: ""
    Leave base-url, listen-http, behind-proxy, firebase-key-file, auth-file, and visitor-request-limit-exempt-hosts as they are. Do not set upstream-base-url: https://ntfy.sh.
    bash
    sudo systemctl restart ntfy
    Paste: the two-line grep of auth-default-access and upstream-base-url from the live file.
  3. Unauthenticated curl to a topic → 403. Authenticated Recheck → 200. Paste: both curl status lines (no tokens).
  4. One iPhone + one Android: swipe-away banner shows a real title/body, not only “New message”. Paste: both banners (crop site names).
  5. NAS note: cutover date, “deny-all applied”.

Verify

  • [ ] Anonymous publish/subscribe fail
  • [ ] Authenticated SafeCall publish works
  • [ ] Keryx FCM/APNs still wakes with usable banners
  • [ ] auth-default-access is deny-all on the live host

Evidence: NAS evidence/keryx/YYYY-MM-DD-oa-119-ntfy-cutover.txt. Tick log: OA-119-ntfy-cutover → done. GitLab: Note on #166. Do not reopen #119 unless banners fail.

Forbidden: Applying this on hetest2 while the official ntfy app is still the administrator client; upstream-base-url: https://ntfy.sh.


Phase 10 — Apple Account Recovery ​

Who: Operator on a new device. Agent: GitLab notes only.

OA-114-apple-recovery ​

Log: Keryx operator actionsHow-to: store-org-and-eu-trader.md (Part A recovery), store-org-evidence-packIssue: #158

Gate: First public Keryx launch has happened (store listing live for Czech customers, not only Internal). Use a new device signed into the company Apple Account (team 8P59575P2K Account Holder).

Stop if you would enable the recovery key on the only existing Mac and call it done — the row requires a new device.

  1. On a new device (not GLaDOS), sign into the company Apple Account (Account Holder, team 8P59575P2K). Paste: Settings showing that Apple Account on the new device (crop email if you want).
  2. System Settings → your name → Sign-In & Security.
  3. Two-Factor Authentication is On. Crop phone numbers. Paste: that 2FA-on screen.
  4. Same page or account.apple.com → Sign-In & Security → Account Recovery / Recovery Key. Enable it. Finish Apple’s confirmations (usually the device passcode).
  5. Put the recovery key only in Apple Passwords. Never in this chat, git, or a NAS text file.
  6. NAS evidence/keryx/YYYY-MM-DD-oa-114-apple-recovery.txt: recovery key enabled on new device; key lives in Apple Passwords. Paste: that NAS note. Never the key.

Verify

  • [ ] New device, company Apple Account
  • [ ] Recovery key exists in Apple Passwords only
  • [ ] NAS note has location, not the key

Evidence: NAS evidence/keryx/YYYY-MM-DD-oa-114-apple-recovery.txt. Tick log: OA-114-apple-recovery → done. GitLab: #158 may close.

Forbidden: Pasting the recovery key into File Browser text files or GitLab; enabling the key only on GLaDOS and calling it done.


After each chapter (repeat) ​

  1. Paste the chapter’s Paste screenshots in this Cursor chat (agent ticks the steps).
  2. NAS evidence path updated (secret-free).
  3. Matching row in keryx/operator-actions.md: status done, date, Verify [x].
  4. Secret-free GitLab note on the linked iid (if any).
  5. Close the iid only when that chapter says you may.

Do not invent a third owed-list. If a new portal step appears during the sitting, add a row to the Keryx log in the same docs change.

Master checklist ​

Prep

  • [x] Phase 0 — NAS unlocked (17 September 2026)

Pending

  • [x] OA-112-ci-enable (17 September 2026)
  • [x] OA-132-intake-drill (17 September 2026)
  • [x] OA-129-hotfix-tabletop (17 September 2026)
  • [x] OA-keryx-status-sidecar (19 September 2026)
  • [x] OA-121-app-walk (19 September 2026)
  • [x] OA-116-device-a11y (skipped 20 September 2026; #116 closed)
  • [x] OA-123-review-host (20 September 2026; #123 closed)
  • [x] OA-legal-cs (20 September 2026; #108 closed)
  • [x] OA-107-https (20 September 2026; /keryx/review 200)
  • [x] OA-125-listings (21 September 2026; #125 close)

Pending

  • [x] OA-126-submit (21 September 2026; Apple rejected 23 September 2026; #126 stays open)
  • [ ] OA-126-apple-resubmit (same binary 1.0 (18); EN+CS metadata)
  • [ ] OA-165-nse (#165)
  • [ ] OA-119-ntfy-cutover (after public install + NSE; #166)
  • [ ] OA-114-apple-recovery (after public launch, new device)