Archived
397 lines
25 KiB
Markdown
397 lines
25 KiB
Markdown
# Project status and handoff
|
||
|
||
Last updated: 2026-10-03 (native chat offline qualification; no live chat/deployment qualification).
|
||
|
||
Reusable implementation, testing, device and deployment lessons are in
|
||
[ENGINEERING_LEARNINGS.md](ENGINEERING_LEARNINGS.md). September 12 test/install
|
||
results below are historical evidence, not a September 19 health check.
|
||
|
||
## Unified native Hope chat — 2026-10-03
|
||
|
||
The explicit unified-parity request supersedes historical no-model-picker notes.
|
||
Native **Chats** is now the default authenticated shell, alongside unchanged Talk
|
||
and Activity access. HTTP text chat uses the same verified account/bearer and
|
||
pinned, ephemeral, redirect-denying networking; it requires neither LiveKit nor
|
||
microphone capture. Durable server conversations, search, paging, workspaces,
|
||
pins, archive, move, rename and confirmed delete are supported. Branch/edit/
|
||
regenerate preserve original history. SSE full-message replacements deduplicate
|
||
monotonic replay IDs, expose progress/approval/stop and explicit resume after
|
||
interruption. Foreground metadata sync is account-scoped, five-second, cancels on
|
||
background/logout, and preserves drafts/read position. Text selection, fenced-code
|
||
copy, headings/lists/links use native rendering (no remote WebView).
|
||
|
||
The backend-generated semantic Opal/Graphite/Ocean/Sage/Lavender artifact is
|
||
consumed by native chat; appearance and palette persist through authenticated
|
||
preferences. Model/thinking controls use only `/api/settings/model`, never a
|
||
direct upstream connection. Chat → Talk binds `/token` to the selected durable
|
||
conversation after existing room teardown; nil legacy bootstrap stays supported.
|
||
Keychain origin scope, auth verification/logout sequencing, exact TLS pins and
|
||
existing voice lifecycle invariants were not weakened.
|
||
|
||
Advanced UI follows the new `CHAT_FEATURES_CONTRACT`: capability-gated private
|
||
Files/Photos uploads (8 MiB client cap; up to eight selected IDs), in-memory
|
||
text/image/PDF preview, artifacts with revision edit/history/text share, scheduled
|
||
task create/edit/pause/resume/run/delete and revision-aware memory controls.
|
||
Uploads do not automatically send. Task execution is server-owned; there is no
|
||
APNs/push or task output history claim. Images/research show only after explicit
|
||
server qualification. Memory changes may require a later Hermes session.
|
||
Connectors and fabricated integration switches are not shown. Advanced data,
|
||
previews/drafts, replay tasks and exports clear during account teardown.
|
||
|
||
Offline verification: initial 66 unit + 2 chat UI passed; expanded 67 unit + 10 UI
|
||
(7 existing voice + 3 chat) passed at `/tmp/hope-chat-final-tests.xcresult`.
|
||
Extra HTTP transport coverage then passed 69 unit + 3 chat UI at
|
||
`/tmp/hope-chat-qualified-tests.xcresult`. An earlier artifact UI run failed an
|
||
exact row label assertion (native label includes revision/kind); predicate fixed,
|
||
failed evidence retained at `/tmp/hope-chat-advanced-tests.xcresult`.
|
||
Final current-source run passed **70 unit + 4 chat UI tests**, zero failures,
|
||
`/tmp/hope-chat-final-qualified.xcresult` and `/tmp/hope-chat-final-qualified.log`.
|
||
Retained Chat, Workspaces, Appearance (accessibility XXXL), and Artifact screenshots
|
||
were exported to `/tmp/hope-chat-screenshots/` and visually inspected. Screens use
|
||
native navigation/forms and readable Opal tint; appearance title truncates at XXXL
|
||
as standard large-title behavior, controls remain reachable/scrollable.
|
||
Signed generic iPhone build passed at `/tmp/hope-chat-phone-build.log`, artifact
|
||
`/tmp/hope-chat-phone-build/Build/Products/Debug-iphoneos/Voice.app`. Final current
|
||
source signed build passed again at `/tmp/hope-chat-phone-final-build.log`. No installation,
|
||
production requests, backend deployment or physical speech qualification occurred.
|
||
Opt-in live TLS cases return without probes in offline suite and are not TLS proof.
|
||
|
||
Native follow-up: named `.md`/`.json` conversation and `.md`/`.txt` artifact
|
||
Transferable file exports preserve bytes and keep no persistent private cache;
|
||
exports clear on conversation switch/logout. Basic markdown tables render selectable
|
||
native rows. Polling uses weak account lifetime, teardown/deinit cancellation, and
|
||
background stream cancellation with foreground replay. Explicit standard-size UI
|
||
fixtures now distinguish default screenshots from XXXL accessibility fixtures.
|
||
Follow-up **70 unit + 5 chat UI passed** at `/tmp/hope-chat-polish-final.xcresult`;
|
||
signed current build passed `/tmp/hope-chat-phone-export-final.log`. Standard
|
||
light/dark chat and dark list screenshots exported to
|
||
`/tmp/hope-chat-standard-screenshots/` and inspected. Conversation captures retain
|
||
the active keyboard; dark list capture shows full shell. Initial new dark UI test
|
||
failed the combined native picker label and was corrected; failed bundle retained
|
||
`/tmp/hope-chat-polish-tests.xcresult`. No hardware installation or live request.
|
||
|
||
Physical follow-up — 2026-10-03: parent reported installation and ordinary launch
|
||
of the signed app succeeded around 12:04–12:05. Added `ChatLiveTests`, deliberately
|
||
opt-in with protected environment credentials; offline simulator compile/test
|
||
explicitly **skipped one live test**, zero failures, at
|
||
`/tmp/hope-chat-live-optin-compile.log`. One authorized physical HTTP attempt used
|
||
native pinned login and a disposable chat (no memory/preferences mutations).
|
||
It **failed**, not passed: `/tmp/hope-chat-physical-qualified.xcresult` reports
|
||
one failed test, zero passed, "test runner exited with code 0 before finishing";
|
||
outer xcodebuild exited 65. Evidence `/tmp/hope-chat-physical-qualified.log` and
|
||
`/tmp/hope-chat-physical-summary.json`. App-host logs also show interactive voice
|
||
connections and microphone enable while the HTTP probe was running; the probe
|
||
itself calls no voice API. Concurrent user interaction is possible, not proven
|
||
causal. Do not claim no audio captured or successful physical chat qualification.
|
||
Cleanup after host exit is unconfirmed; parent should inspect only admin-owned
|
||
chat titled **Native qualification · disposable**, never unrelated user chats.
|
||
Further native live attempts stopped at parent's request while user uses voice.
|
||
No test-host UI guard was retained and no subsequent device action performed.
|
||
|
||
## Approved Opal pink redesign — 2026-10-02
|
||
|
||
User approved the Opal HTML direction with the existing square reactive persona.
|
||
Native implementation now uses luminous pink-white surfaces, readable plum text,
|
||
rose actions (#A64270), an account-derived personalized greeting, 184pt welcome /
|
||
112pt active Canvas presence, pastel starter prompts, and an inset floating dock.
|
||
The approved Opal overlapping-speech icon replaces the old glowing capsule.
|
||
Light/dark semantic roles, Dynamic Type and Reduce Motion remain supported.
|
||
Sign out moved into the Account menu; authentication, TLS, session lifetime,
|
||
account-scoped history, draft retention, transcript follow-latest behavior and
|
||
voice/text readiness gates are unchanged. Starter prompts prepare editable text
|
||
only: they never send automatically or enable microphone capture.
|
||
|
||
Verification: simulator and signed generic-iPhone builds passed. Full offline run
|
||
passed **59 unit + 7 UI tests**, `/tmp/hope-opal-offline.xcresult`; three explicitly
|
||
opt-in TLS unit cases returned without live probes, not runtime TLS evidence.
|
||
Independent review identified editor disappearance on clearing a prompt; corrected
|
||
by keeping the Type draft editor mounted even when empty. Final focused draft-edit /
|
||
offline recovery run passed **2 UI tests**, `/tmp/hope-opal-draft-final.xcresult`.
|
||
Final pink idle-persona tint change rebuilt and **59 unit tests passed** again,
|
||
`/tmp/hope-opal-final-unit.log`. Native light/dark simulator screenshots inspected;
|
||
light screenshot `/Users/shane/dev/hope-voice-api/design-options/opal-native-light.png`.
|
||
|
||
Initial physical install reset its transport, then retry was explicitly denied
|
||
because the iPhone was locked. After the user unlocked it, final signed build,
|
||
installation and launch **succeeded** on the paired iPhone 14 Pro Max at 13:27 local.
|
||
Artifact `/tmp/hope-opal-phone-build/Build/Products/Debug-iphoneos/Voice.app`, final
|
||
build log `/tmp/hope-opal-phone-install.log`. App data/credentials were preserved.
|
||
No backend, account data, saved credentials or production preferences were reset.
|
||
Real microphone capture, audible replies and interruptions were not requalified
|
||
by this UI work; successful installation is not a live voice-session claim.
|
||
|
||
## Authorized Hermes migration — 2026-10-01
|
||
|
||
The direct user request supersedes the historical Qwen/client-model direction below.
|
||
This repository now implements server-account login (`/api/auth/login`), bearer
|
||
verification (`/api/auth/me`), logout (`/api/auth/logout`), and authorized `/token`
|
||
bootstrap. Hermes is server-managed: model settings, pickers and control messages
|
||
were removed. No backend source, deployment, live endpoint or secrets were touched
|
||
in this iOS implementation.
|
||
|
||
- Bearers live in device-only, unlocked Keychain items scoped to canonical HTTPS
|
||
origin; passwords are never persisted. Login accepts numeric Unix expiry and
|
||
ISO8601 expiry, and ready/provisioning accounts.
|
||
- Logout and origin replacement invalidate auth work, cancel bootstrap and
|
||
disconnect transport before removing the account UI. Each account/root gets
|
||
fresh drafts/tasks and history scoped to origin + immutable user id; the global
|
||
legacy `voice_history` is never imported.
|
||
- Signaling is same-origin WSS `/livekit` for all hosts, including IPv6/private
|
||
addresses. Userinfo/query/fragment origins are rejected. There is no plaintext
|
||
fallback and no trust-all delegate. HTTP retains the existing exact LAN pin;
|
||
**the LiveKit SDK's separate WSS trust may require an installed trusted CA**.
|
||
Self-signed WSS, actual login, multi-user server isolation, microphone capture,
|
||
audible speech and interruptions require subsequent user hardware qualification.
|
||
- `assistant-progress` working/completed/failed events display request activity
|
||
without polluting eventual normal transcripts. Payload logging is removed; SDK
|
||
log level is error rather than release debug.
|
||
- Offline UI uses fake auth and memory token storage plus isolated preferences;
|
||
bootstrap fixtures cannot contact a remote server. Live suite is excluded from
|
||
this validation. `project.yml` generates sources and an explicit test scheme.
|
||
|
||
Verification: simulator build passed. Initial offline unit run: **50 passed, 0
|
||
failed** (5 new focused authentication tests), `/tmp/hermes-ios-unit2.xcresult`.
|
||
A scheme-less first test attempt failed before running tests; adding the generated
|
||
scheme fixed it. Combined offline run: **51 unit + 5 UI passed, 0 failures** at
|
||
`/tmp/hermes-ios-offline-final.xcresult`. Expanded run added the logout/account-switch
|
||
privacy UI test, which passed; one existing URL normalization assertion raced the
|
||
asynchronous save render and failed. It now waits for the saved confirmation before
|
||
asserting the normalized value. A subsequent accessibility-size Activity empty-state
|
||
assertion timed out after 5 seconds; its wait now allows 15 seconds. Both failed-run
|
||
bundles are retained (`/tmp/hermes-ios-offline-qualified.xcresult` and
|
||
`/tmp/hermes-ios-offline-release.xcresult`). Final focused re-verification:
|
||
**51 unit + 3 UI passed, 0 failures**, including accessibility-size navigation,
|
||
settings persistence/normalization and logout/account-switch transcript/task privacy,
|
||
`/tmp/hermes-ios-focused-final.xcresult`. Remaining three offline UI cases passed in
|
||
both expanded runs. Parent security review identified transient `/me` outages clearing
|
||
Keychain prematurely; fixed to clear only 401/403 and added a regression test.
|
||
Final source: **52 unit passed, 0 failures**, `/tmp/hermes-ios-unit-final.xcresult`.
|
||
All six offline UI cases have passed across the runs described above; the final
|
||
three focused cases passed together. No claim of one fully green expanded six-UI
|
||
run is made. These are client-only simulator claims, not live/deployment/hardware
|
||
qualification.
|
||
|
||
## Physical iPhone deployment — 2026-10-01
|
||
|
||
At the user's request, compiled the current Hermes account app with Xcode 26.4
|
||
using automatic development signing (`Voice_iOS`, Debug, generic iOS destination).
|
||
Build succeeded; artifact `/tmp/hope-voice-phone-build/Build/Products/Debug-iphoneos/Voice.app`,
|
||
build log `/tmp/hope-voice-phone-build.log`. Installed bundle `dev.shane.voice`
|
||
on the connected, paired iPhone 14 Pro Max (iOS 26.7.1, Developer Mode enabled).
|
||
Installation reported success. The first automatic launch was denied because the
|
||
iPhone was locked (`FBSOpenApplicationErrorDomain: Locked`). After the user unlocked
|
||
it, `devicectl device process launch` succeeded and launched `dev.shane.voice`.
|
||
No credentials/preferences were reset, no backend changes, and no physical speech
|
||
or authenticated WSS qualification is implied by successful installation.
|
||
|
||
## Square presence and certificate onboarding — 2026-10-01
|
||
|
||
User reported invalid server certificate at sign-in and requested the webapp square
|
||
presence as the primary native avatar. Replaced Lightwell rendering with an efficient
|
||
21×21 Canvas LED matrix, centered 220pt on welcome and 136pt above active transcript;
|
||
smaller accessibility sizes preserve controls/readability. Mic/listening and agent
|
||
speech levels drive separate patterns; Reduce Motion freezes motion/audio geometry.
|
||
Existing semantic theme and single accessible status are preserved.
|
||
|
||
Actual deployed leaf and SPKI pins match the app. Explicit live native HTTPS probe
|
||
passed on both simulator and physical iPhone against `/api/auth/me` (expected401,
|
||
no credentials). Physical native password POST reached server and returned401 for
|
||
John Doe; user confirmed deleting this test account, so no account was recreated.
|
||
No TLS bypass, plaintext fallback, or pin change was made. The reported original
|
||
login failure was not reproduced by this test; installed-version or transient cause
|
||
is not conclusively established. Admin full-auth test was interrupted by lock/lost
|
||
testmanager connection, not claimed successful.
|
||
|
||
LiveKit's SDK uses an independent system-trust WebSocket session. User approved a
|
||
public certificate-only installation profile, exact leaf SHA256
|
||
`07907abde3bb9c685265909927627d9ea4705d7e7b27056eefe06e10b192af46`.
|
||
Profile is served at `https://192.168.86.2:9178/hope-server.mobileconfig`, requires
|
||
manual installation and full trust in iPhone Settings. App login links it only
|
||
for the exact configured LAN host/port, and certificate errors include safe recovery.
|
||
An initial container-copy download disappeared after another backend deployment;
|
||
fixed by persistent cert mount and exact nginx alias; verified200/apple profile MIME,
|
||
private-key path404. Nothing installs trust automatically or weakens TLS checks.
|
||
|
||
Validation: 19 conversation tests passed (3 new LED tests), simulator screenshots
|
||
`/tmp/hope-led-welcome-ready.png` and `/tmp/hope-led-history-dark.png`. Complete
|
||
unit suite:58 passed, including two explicit-opt-in live TLS cases skipped in offline
|
||
run. Actual opted-in physical HTTPS test passed separately. New live tests use
|
||
environment-only credentials, never fixtures/source/argv. Updated signed phone
|
||
build passed (`/tmp/hope-square-phone-build.log`) and app installed/launch succeeded
|
||
on the iPhone14ProMax (`dev.shane.voice`, 18:00 local). Physical speech remains user qualification.
|
||
|
||
Follow-up: user installed profile/full trust but SDK still reported validation cert
|
||
invalid. Reproduced physically: exact pinned HTTPS passed; system URLSession HTTPS
|
||
failed -1202/-9807. Controlled A/B removed redundant `NSPinnedCAIdentities` in
|
||
XcodeGen (normal iOS trust, HTTPS/WSS and exact HTTP leaf pin remain unchanged).
|
||
System trust then passed on same phone, establishing ATS CA-only rule conflict,
|
||
not proven certificate validity-length rejection. Final physical native live test
|
||
**3 passed**: pinned HTTPS, system-trusted HTTPS, and admin login/me/bootstrap →
|
||
actual LiveKit SDK authenticated WSS connect/disconnect → logout; no microphone
|
||
enabled. Evidence `/tmp/hope-phone-wss-qualified.log`. John Doe remains deleted.
|
||
Signed corrected build passed `/tmp/hope-square-tls-fixed-build.log`.
|
||
|
||
|
||
## Current direction
|
||
|
||
Keep **Qwen 2.5**. The user explicitly canceled the earlier request to switch to
|
||
a ChatGPT subscription/device-token login. Do not revive that migration because
|
||
an old saved goal mentions it. Current work is the native iOS UI/UX redesign
|
||
and end-to-end qualification.
|
||
|
||
**2026-09-12: the embedded music player was removed** by user decision — the
|
||
feature is gone from the app (Media tab, `Sources/Media/`, `MediaPanelView`,
|
||
`MediaAPI`, `MediaPlayerController`, `PinnedMediaResourceLoader`, media tests,
|
||
and the `media_state` control publish). The backend media API still exists and
|
||
is untouched. The backend AAC compatibility patch (below) is now irrelevant to
|
||
the iOS app but remains deployed.
|
||
|
||
The **Nearlight** native redesign is implemented across Talk, Activity, Settings,
|
||
pickers, task details, and connection diagnostics. Current simulator qualification
|
||
is green, and GPT-6 Astra's final blocker re-verification returned **PASS**. The
|
||
final source also produced a signed generic-iOS build, and once the phone
|
||
reconnected the final build was installed and launched on the paired iPhone.
|
||
Hardware audio and interruption qualification remains open.
|
||
|
||
## Completed work
|
||
|
||
### Native interface and usability
|
||
|
||
- The app now has native **Talk** and **Activity** tabs sharing one session;
|
||
changing tabs never ends a conversation.
|
||
- Implemented Astra's **Nearlight** direction: an adaptive plum/rosewood semantic
|
||
palette, restrained rounded typography, shared spacing/radius/motion tokens, and
|
||
the compact Lightwell aperture as the conversation state signature.
|
||
- Rebuilt Talk around a clear pre-connection welcome, Voice/Type choice, explicit
|
||
start/end controls, compact active status, microphone meter, persistent Type
|
||
draft, and a dock that keeps primary actions reachable.
|
||
- Reworked the transcript as a readable shared record with speaker/time metadata,
|
||
live partials, copy/selection, explicit destructive confirmation, and measured
|
||
follow-latest behavior. Restored history stays at the top; manual reading,
|
||
selection, and VoiceOver row focus suspend following until **Latest**.
|
||
- Made connection and ready-session microphone failures visible without discarding
|
||
the real error. Permission denial exposes an iPhone Settings recovery action;
|
||
Type mode remains available.
|
||
- Reworked Settings around voice, mode, model, and connection. Server edits are
|
||
validated and explicitly saved; normalization confirmation survives session
|
||
replacement and clears on the next user edit.
|
||
- Improved Activity hierarchy, active-count badge, empty state, state-specific
|
||
rows, and task detail presentation.
|
||
- Removed forced dark appearance; all redesigned surfaces support light/dark mode,
|
||
Dynamic Type, Reduce Motion, increased contrast branches, and 44-point-or-larger
|
||
interaction targets where applicable.
|
||
|
||
### Functional fixes
|
||
|
||
- Observed nested transcript, conversation-state, and task objects so asynchronous
|
||
updates render.
|
||
- Preserved latest-wins server replacement while keeping an open Settings
|
||
navigation stack and its success feedback intact.
|
||
- Preserved Type-mode microphone privacy, pending-message send gating, clean session
|
||
teardown, transcript persistence/deduplication, and interruption ordering.
|
||
- All media-related client behavior was removed with the music player on 2026-09-12.
|
||
|
||
### Tests and tooling
|
||
|
||
- Follow-up commits added the Lightwell app icon (`7ac8a1c`) and regenerated the
|
||
project to include its asset-catalog resource phase (`85169d6`). The qualification
|
||
results below predate those follow-ups; do not describe them as a fresh full run
|
||
of the current HEAD.
|
||
- Installed XcodeBuildMCP and its skills; used it for simulator build/run/test work.
|
||
- The current combined simulator run passed **50 tests, 0 failures**, with the
|
||
opt-in live suite skipped once. Five offline UI scenarios cover recovery,
|
||
settings validation/persistence and save feedback, transcript/task flows,
|
||
restored-history reading position, and accessibility-size navigation.
|
||
- A post-focus-change targeted restored-history UI regression passed independently.
|
||
- DEBUG UI fixtures use isolated preferences; ordinary application preferences and
|
||
the NAS are not modified by offline UI runs.
|
||
- GPT-6 Astra completed the design specification and four verification rounds. Its
|
||
final scoped review found B1–B3 resolved, N1/N2 preserved, and no concrete
|
||
remaining release blocker. Accepted visual/adaptive/accessibility polish remains
|
||
documented as debt, not as exhaustive WCAG or VoiceOver qualification.
|
||
|
||
## Backend deployment and cross-repository dependency
|
||
|
||
SSH host: `[email protected]` (Unraid). App URL: `https://192.168.86.2:9178`.
|
||
|
||
- `voice` image: `hope-voice-api-voice:68f4c46-ios-audio`, host networking,
|
||
restart policy `unless-stopped`. Includes LiveKit, voice agent, token service,
|
||
media API, and nginx.
|
||
- LLM: `qwen2.5-vl-3b` through existing OpenWebUI at
|
||
`http://192.168.86.2:3005/api`. Existing Azure speech configuration retained.
|
||
- `voice`, `open-webui`, and `local-vl-models` were present and healthy when the
|
||
user suspected deletion. Do not recreate healthy services unnecessarily.
|
||
- Original library, certificates, and skills were retained under
|
||
`/mnt/user/dev/hope-voice-api`; the dirty remote checkout was not overwritten.
|
||
- Separate deployment source: `/mnt/user/dev/hope-voice-deploy-68f4c46`.
|
||
- Stopped rollback container: `voice-before-ios-audio`.
|
||
- Backend AAC conversion preserves original WebM files and serves cached AAC with
|
||
byte-range support. Browser/raw requests retain their original behavior.
|
||
|
||
**Important:** the backend patch and its test are in a different local repository:
|
||
`/Users/shane/dev/hope-voice-api/web/media_server.py` and
|
||
`/Users/shane/dev/hope-voice-api/tests/test_ios_audio.py`. They were still uncommitted
|
||
at the earlier deployment handoff; their current sibling-repository status has not
|
||
been rechecked in this documentation update. Committing/pushing the iOS repository
|
||
does **not** publish those files.
|
||
The deployed image contains the patch, but a future backend CI rebuild can lose it
|
||
unless it is committed and deployed through that repository's workflow. Inspect
|
||
that workflow before pushing: it may replace the live container.
|
||
|
||
Launch configuration and rollback details: [DEPLOYMENT.md](DEPLOYMENT.md).
|
||
Do not copy credentials or `.env` contents into documentation or commits.
|
||
|
||
## Verification performed
|
||
|
||
Project `Voice.xcodeproj`, scheme `Voice_iOS`, iPhone 17 Pro simulator
|
||
`AFDA137E-1657-428E-BF01-E5CD7989772C`.
|
||
|
||
- Current combined run: **50 passed, 0 failed, 1 live skip** in 104.9 seconds.
|
||
Result bundle:
|
||
`test_sim_2026-09-12T14-03-09-058Z_pid95846_2ca9da7e.xcresult`.
|
||
- Post-focus-change restored-history regression: **1 passed, 0 failed**.
|
||
Result bundle:
|
||
`test_sim_2026-09-12T14-05-21-070Z_pid98187_bd3e531a.xcresult`.
|
||
- A fresh isolated simulator launch showed restored history top-anchored with
|
||
**Latest** visible; the UI regression then tapped Latest and verified the final
|
||
event became visible.
|
||
- Astra's targeted isolated runtime check verified a padded changed-address save
|
||
stays in Settings, normalizes the field, shows its checkmark and confirmation,
|
||
and clears both only after the next user edit. Final verdict: **PASS**.
|
||
- iPhone 14 Pro Max `BF93D35E-0853-5470-A125-6EB0DB3F17AB` was paired, signed,
|
||
installed, trusted, and launched successfully. The final Nearlight build
|
||
(`/tmp/voice-ios-device-derived/Build/Products/Debug-iphoneos/Voice.app`,
|
||
`dev.shane.voice`) was reinstalled and launched via `devicectl` after the phone
|
||
reconnected. Free provisioning expires after seven days; reinstall to re-sign.
|
||
- Historical live NAS runs verified Qwen replies, background task completion, and
|
||
reconnect. Backend integration remains 16 passed, 7 skipped, 2 deselected.
|
||
|
||
Exact historical qualifications: [VERIFICATION.md](VERIFICATION.md). Artifacts
|
||
live on this Mac under the XcodeBuildMCP workspace, not in Git.
|
||
|
||
## What remains, in order
|
||
|
||
1. **Qualify real audio:** microphone capture, TTS audibility, speaker/headphones,
|
||
barge-in, Siri/phone interruptions, lock/background behavior,
|
||
microphone-permission-denied fallback, and network-loss recovery. These require
|
||
the user's speech/listening or a real interruption; simulator state tests do not
|
||
prove them. Follow [DEVICE_TESTING.md](DEVICE_TESTING.md).
|
||
2. **Broader live regression:** exercise slow-network cancellation, network-loss
|
||
recovery, repeated server replacement, and voice/model selection against the
|
||
live agent.
|
||
3. **Manual accessibility/visual qualification:** inspect populated/error screens
|
||
in light and dark mode, accessibility text sizes, narrow/landscape layouts, and
|
||
a real VoiceOver focus session. Astra accepted the remaining presentation debt
|
||
for this personal-app release; that is not proof of exhaustive conformance.
|
||
4. **Publish the backend compatibility source safely** in the sibling repository
|
||
and ensure its normal deployment preserves mounts, certificates, and Qwen
|
||
settings. This is lower priority because the iOS app no longer consumes the
|
||
media API, but the deployed container still serves it for the web UI.
|
||
|
||
## Repository handoff
|
||
|
||
The iOS work and this report belong to branch `feat/ios-app`, remote `origin`
|
||
(`https://git.srmr.xyz/snowspeeder/hope-voice-ios.git`). Keep the Nearlight
|
||
implementation, tests, physical-device notes, and this handoff together when
|
||
committing. Check Git history and remote status for the final publish result.
|