Skip to content

fix(ios): refuse observe-only snapshots that find a system alert - #4219

Merged
thymikee merged 3 commits into
callstack:mainfrom
airowe:worktree-fix-3348-observe-only-alert
Nov 4, 2026
Merged

thymikee merged 3 commits into
callstack:mainfrom
airowe:worktree-fix-3348-observe-only-alert

Conversation

@airowe

@airowe airowe commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

snapshot --observe-only could answer with the SpringBoard alert tree while still stamping observation, which asserts the tree came from the session app. It now refuses with OBSERVATION_UNAVAILABLE and a hint naming the alert. The docs already promised no substitution, so this refuses rather than discloses. Regular snapshots are unchanged.

Closes #3348. 7 files. The fast and raw alert tiers fold into one function, so the refusal has one owner.

An alert the runner cannot read still leaves the app tree as the answer, so a success does not prove that no alert is present. The docs now say so.

Validation

pnpm check:affected --run --head de9eaf985: 13 passed, 9 skipped, exactCommit=true. Skipped includes swift-runner-ios, swift-runner-macos and the replay lanes.

Unit, iPhone 17 simulator: testObserveOnlySnapshotRefusesOnlyASubstitutedSystemAlertTree failed before the fix and passes after.

Live, same simulator, real Maps location alert, on the Swift in this PR (run before committing; later commits change only help, docs and a test assertion):

  • snapshot returns the alert tree.
  • snapshot --observe-only and --observe-only --raw exit 1 with OBSERVATION_UNAVAILABLE.
  • After alert dismiss, --observe-only succeeds with observation.

Not done: a typed reason for this refusal. The issue asks for the existing response, and the message still reads "cannot be observed without activation"; only the hint names the alert.

Independent review of 9d34cf9b1 found no correctness defects.

🤖 Generated with Claude Code

The system-alert tier answered an observe-only capture with the
SpringBoard alert tree, and the response still carried observation
metadata that asserts the tree came from the session app. The docs
already promise no substitution, so an observe-only capture now refuses
with OBSERVATION_UNAVAILABLE and a hint naming the alert. Regular
snapshots keep returning the alert tree.

Fold the fast and raw alert tiers into one function so the refusal has
a single owner.

Closes callstack#3348
Versioned help owns command semantics, so it now names the refusal. The website wording also stops implying that a success proves no alert is present.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

@thymikee

thymikee commented Nov 4, 2026

Copy link
Copy Markdown
Member

At de9eaf9, the code looks good. An observe-only capture now refuses a substituted system-alert tree with OBSERVATION_UNAVAILABLE, and that decision has one owner, the capture-tier function that returns the substitution. The production Swift is identical to the live-validated commit 9d34cf9. The hint assertion thread is fixed, since the test now asserts the hint exactly for both legs.

Not blocking, take or leave: the alert hint is a string literal at the catch site in RunnerTests+SnapshotExecution.swift:142 and the test restates it. A named static next to observeOnlyUnavailableResponse, or text carried by SystemAlertSubstitutionRefused, would keep one copy.

The Coverage job is red, but its log ends mid-run without a failing assertion, and this PR changes only one help string that the unit job exercises. A rerun should settle it. No conflicts are known.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Nov 4, 2026
@thymikee
thymikee merged commit f3b8ab3 into callstack:main Nov 4, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ios: snapshot --observe-only can label a substituted system-alert tree as an app observation

2 participants