--- name: obsidian-ios-real-device-smoke description: Validate Personal Assistant on an iPhone using the iCloud test vault and Safari Web Inspector. Use only for an explicit real-device request or a verified iOS-specific capability requiring device evidence. General mobile UI and Obsidian CLI mobile simulator validation use obsidian-test-vault-smoke. --- # Obsidian iOS Real-Device Smoke ## Core Rules - Select this skill under the mobile environment rule in `AGENTS.md` and name the user request or verified iOS-specific capability. Device selection does not itself authorize deployment or interaction; an Agent-authored plan or a simulator/tool failure cannot create that requirement or authorization. - Do not claim iOS real-device validation for a plugin-asset change unless the current build was written to the iCloud Obsidian `test` vault, all copied assets matched `dist`, the loaded plugin identity matched that artifact, and the affected behavior was observed on the connected iPhone. - If only a vault-resident smoke runner changed, sync and hash-check that runner, then re-evaluate it in the existing page. Do not redeploy or reload the plugin when `dist` and plugin runtime assets did not change. - Treat Safari Web Inspector as DOM/CSS/console/network evidence, not touch automation. Use iPhone Mirroring or the user for real touch interaction. - Discover and use the available native UI tools for Safari and iPhone Mirroring; do not require or install a legacy skill by name. If no tool can operate the real target, report the blocked evidence instead of substituting emulation. For Safari Console JavaScript, use a real paste/input event and verify the command entered Console history or produced its sentinel before counting execution. Accessibility `set_value` may change the displayed editor text without creating executable Web Inspector input, so it is never submission evidence by itself. - Treat an explicit user request to run iOS real-device smoke as authorization for plugin-asset deployment through `make deploy-icloud` (or its current-build reuse target), or the existing scoped preparation/sync command for a runner-only change, targeting only the iCloud `test` vault. Do not ask again. If the user requested only planning, review, or inspection without a real-device run, do not deploy or sync. - Choose the smallest lane that covers the latest runtime delta and stop once that lane has sufficient current-build evidence. - Judge a targeted canary against its current Decision/Spec/SDD contract, not a stricter topology borrowed from a deterministic Desktop fixture. In particular, a live Recovery canary must accept an intended reranker fail-open followed by `recovery_relaxed / skipped / not_eligible` when the standard attempt already returned usable evidence; require an actual relaxed retry only when the canary explicitly owns a deterministic valid-none/partial fixture. Likewise, lexical `unavailable / feature_disabled / generation absent` to `ready / generation present` with an advanced maintenance epoch is a valid first-generation transition. Preserve a raw runner false-negative, classify its product observations independently, and do not spend another device attempt solely to satisfy the invalid assertion. - Before spending a submitted Console execution on a cancellation-only runner, require its post-load Memory plan to be `ready / none`. A fresh plugin reload with persisted rollout flags off may expose the existing lexical generation as `feature_disabled`; temporarily turning flags on then correctly requires preparation and is not a runnable cancellation precondition. Do not convert that setup-only `BLOCKED` into a product failure or repeat the command. - Give every submitted attempt a unique result filename and copy/hash its raw receipt before the next attempt. Never let a retry overwrite the only device evidence. If historical tooling already overwrote a receipt, disclose that limitation and distinguish any retained projection from the unavailable raw file; do not describe the projection as immutable full evidence. - Apply slice-scoped invalidation after a diagnostic-only repair. When an immutable real-device receipt already proves cancel request/observation, late discard, zero accepted-after-cancel, stable index identity and queue release, a successor that changes only terminal classification may close through exact new-artifact load identity plus a regression using the real wrapped `AbortError` shape. Do not rebuild Memory or spend another Provider/device attempt solely to replay the unchanged Worker/queue behavior. ## Change Lanes | Lane | Use when | Required iPhone evidence | Skip | | --- | --- | --- | --- | | `geometry-only` | CSS/layout/position/size changed; gesture and action routing did not | Asset match, one reload, one real gesture that exposes the UI, one Mirroring screenshot, one Inspector geometry/hit-test probe, fresh errors | Hold threshold, movement cancel, exactly-once action checks, provider flows, unrelated orientations | | `interaction` | Touch, pointer, keyboard, focus, dismissal, or action routing changed | Geometry basics plus the affected real gestures, cancel path, and exactly-once behavior | Unrelated Pagelet/provider/cross-surface flows | | `broad/release` | Shared mobile runtime, multiple surfaces, packaging, or release gate | The declared cross-surface and orientation matrix | Anything explicitly outside the release scope | Do not promote a geometry-only delta into an interaction or release run merely because more evidence is available. Record unrequested orientations or devices as `NOT TESTED` residuals. ## Device Preflight And Retry Budget Before deployment or GUI control, confirm: - the user requested real-device smoke; - the local prerequisite covers the same runtime source state; - iPhone Mirroring is connected and the device/Mac are unlocked; - Obsidian is on the iCloud `test` vault and intended note; - Safari Develop exposes the current Obsidian target. Allow one unlock/reconnect/reattach sequence, or about three minutes, when a device or Inspector prerequisite is missing. Then report `BLOCKED`; do not keep hunting through menus or coordinates. After a reload, allow at most one Inspector reconnect. If `body.in-progress` persists, preserve the manual path and stop. Use one submitted Console probe that returns all required assertions. Allow at most two execution attempts before reporting partial evidence or `BLOCKED`; submitted-but-ambiguous commands count as attempts. Do not spend additional attempts recovering focus, autocomplete, or stale element indices. Re-read app state after state-changing UI actions or window/DOM changes, and never reuse stale element indices; batch stable prompt entry, execution, and result capture where possible. ## Workflow Prerequisite: complete `obsidian-test-vault-smoke` at least at `app-runtime` tier. 1. Bound the changed surface: ```bash git status --short --branch git diff --stat git diff --name-only ``` 2. Reuse automated local checks with verified inputs/results under `AGENTS.md` **Validation Planning And Reuse**. Complete missing or invalidated **Local Validation Gate** checks, counting checks covered by the selected enclosing command and supplementing the runtime `