Skip to content

Commit e297bb9

Browse files
committed
[docs] record completed iPad recovery and board acceptance
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
1 parent d9d058a commit e297bb9

1 file changed

Lines changed: 124 additions & 52 deletions

File tree

Lines changed: 124 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,138 @@
11
<!-- SPDX-License-Identifier: MIT -->
22
<!-- Part of PyBLE (https://pyble.dev) — see /LICENSE. -->
33

4-
# iPad recovery acceptance continuation
4+
# iPad recovery and app compatibility acceptance
55

66
| Field | Record |
77
|---|---|
88
| Date | 31 October 2026, Asia/Bangkok |
9-
| Scope | Remaining normal-app recovery and affected workflow observations for PYB-006.2 / PYB-008.1 |
10-
| Current outcome | Candidate installation and launch pass; automated native UI execution awaits the device owner's iPadOS authentication |
11-
| Source | PR #40 merged at `6f5b3ea73a70342331fb49d0685938ce2a4cae11`; subsequent planning changes do not change app runtime bytes |
9+
| Scope | Normal-app recovery and affected workflow observations for PYB-006.2 / PYB-008.1; app-only compatibility rows Q01/Q03/Q05/Q07/Q09 |
10+
| Outcome | Exact offline restoration, current-board consent and normal Blocks-generated text recovery observed; final keyboard repair and all five app-only iPad board rows pass within the recorded scope below |
11+
| Current runtime | `bef67bded9e5b83437e3eb0e2ec4be6a4cfd1a64`, app tree `60b3a68b693551af5d83076547c502f69838e052`; PR #41 |
1212
| Candidate | PyBLE Preview `0.3.0 (9)`, normal `lib/main.dart`, signed profile mode, isolated `dev.pyble.recoveryqualification` identity |
13-
| Physical platform | iPad Air 13-inch (M4), model `iPad16,10`, iPadOS `26.6.2` |
14-
| Operator | Automated engineering run on the maintainer's Mac; no independent human review or participant observation claimed |
15-
| Prior results | [Platform observations](02_Platform_Qualification.md); native storage seed/kill/verify is distinct from normal-app interaction acceptance |
16-
17-
## Candidate and initial state
18-
19-
The signed app archive is retained privately as
20-
`local/recovery-implementation/ipad-preview-0309/PyBLE-Preview-0.3.0-9-profile.app.zip`.
21-
Its SHA-256 is
22-
`c91bc6f7e14f421a528668bd3723e3f965d55f79f11ea90fec707a8fb15a4d1a`.
23-
The copied Dart runtime matches merged source; only the isolated native identity
24-
and display name distinguish the installation. Signature verification,
25-
installation and foreground launch passed. The disconnected scan displayed all
26-
five board labels. Discovery alone does not establish a connection or completed
27-
board workflow.
28-
29-
The existing TestFlight `dev.pyble.pyble` installation remains version
30-
`0.2.0 (6)`. The Preview application support files were copied privately before
31-
continuation. The copied SQLite database passes `integrity_check` and contains
32-
zero draft rows and zero content bytes. No storage reset, user-data deletion or
33-
board write was used to establish that initial state.
34-
35-
## Native UI runner attempt
36-
37-
| Step | Actual observation |
13+
| Physical platform | iPad Air 13-inch (M4), model `iPad16,10`, iPadOS `26.6.2`, wired to the maintainer's Mac |
14+
| Operator | Automated engineering run through native XCTest; no independent human review, participant observation or audible VoiceOver evaluation claimed |
15+
| Prior results | [Platform observations](02_Platform_Qualification.md); storage seed/kill/verify is distinct from this normal-app interaction evidence |
16+
17+
## Installed artifacts and continuity
18+
19+
| Runtime | Private archive SHA-256 | Observations |
20+
|---|---|---|
21+
| Merged PR #40 `6f5b3ea` | `c91bc6f7e14f421a528668bd3723e3f965d55f79f11ea90fec707a8fb15a4d1a` | Initial installed identity and five-board discovery; superseded for layout qualification |
22+
| Landscape repair `e54a78a` | `ddf611e85065db05c1622faef59c6eddc5b821dfd1a2702ec0cbb66d093e5a0b` | Unicode lifecycle/offline recovery, current-target consent, empty named draft and classic ESP32 workflow |
23+
| Native dismissal `01a7ac8` | `3a2775d1648fe3a188b89f30912af0b7f771ec08b8c0e3b9f4d0c3d49d33510b` | Blocks-to-Editor recovery and C3 workflow; input-palette geometry defect reproduced |
24+
| Native keyboard guide `bef67bd` | `7d39100283fb2cd9189d448881b788ad5eadfdf813a0e5f36ff9a2850fa6c471` | Clean profile build; exact Dart/AppDelegate source manifest matches the runtime; compiled guide channel present and diagnostic instrumentation absent |
25+
26+
Archives, source manifests, native accessibility trees, screenshots and
27+
`.xcresult` bundles are retained under ignored
28+
`local/recovery-completion/ipad/`; the original baseline archive is under
29+
`local/recovery-implementation/ipad-preview-0309/`. Only bundle/display identity
30+
differs from the normal application. Signature verification and installation
31+
pass. Installs reuse the same Preview container without clearing its data.
32+
33+
The existing TestFlight `dev.pyble.pyble` installation remains `0.2.0 (6)`.
34+
Preview acceptance does not establish a TestFlight-delivered upgrade. Before
35+
these runs, a private backup of Preview application support passed SQLite
36+
`integrity_check` and contained zero draft rows and zero content bytes. No
37+
storage reset established that initial state.
38+
39+
## Recovery observations
40+
41+
The [operator recipe](01_Operator_Recipe.md) and
42+
[normative evidence matrix](../../../specifications/App/current-draft-recovery.md#7-required-evidence-before-acceptance)
43+
remain authoritative. A receipt marked partial below contributes only its
44+
completed assertions; its later failure is retained separately.
45+
46+
| Procedure | Actual result and receipt |
47+
|---|---|
48+
| P01/P04/P06: offline startup and Restore | `offline-restore-radio-target`: terminate the same app/container, explicitly verify Wi-Fi and Bluetooth off, relaunch, inspect exact filename/source, Restore into the disconnected local panel. No connection is required. Original radios restored |
49+
| P02/P03: exact named checkpoint | `classic-unicode-checkpoint`: `/q0309i_e54a/recovery.py`, exact `# café λ` followed by `print(271828)`; native text-value assertion and **Saved locally** after manual checkpoint |
50+
| P05: unresolved decision | Discard Cancel preserves the exact preview. In `classic-discard-loop`, backgrounding to Settings and returning preserves the unresolved recovery prompt |
51+
| P07: editing/lifecycle | Real native typing and multiple acknowledged checkpoints survive process termination/relaunch. On final `bef67bd`, `settled-native-input` injects the complete `print(424242` batch after the full keyboard is visibly settled, obtains exact `print(424242)`, checkpoints and restores it after termination without a board write. Continuous-edit debounce behavior remains covered by automated tests; no unacknowledged final keystroke is promised durable |
52+
| P08: explicit Discard | `classic-discard-loop` completes Cancel, confirmed Discard and terminate/relaunch assertions: the next launch shows Scan without a recovery prompt. Its later folder-tap failure does not erase these observations |
53+
| P09: empty named draft | `classic-readback-empty`: deliberately created `empty.py` checkpoints and returns as a named empty recovery copy; distinct from an empty untitled slot |
54+
| P10: actual Save/Run target | `classic-target-cancel`: both current destination `/recovery.py` and distinct write/write-and-run effects are shown; Cancel retains the draft. The board is deliberately connected after Restore |
55+
| P11/P12: Files destination and completion | `classic-upload-run`: move to the owned folder, cancel Upload, confirm its actual folder/file target, then explicitly confirm Run and observe `271828` with Finished. Real clear/Open readback verifies the Unicode source. Session/epoch mutation races remain covered by automated tests |
56+
| P13: replacement guards | `blocks-handoff-recovery` cancels Blocks handoff over Unicode before later confirming. `c3-replacement-finite` and its resume cancel Editor New and board Open over the meaningful generated draft; source remains exact |
57+
| P14 / DR-T12: generated text | `blocks-handoff-recovery`: ordinary Hello example generates exact `print('Hello, PyBLE!')` plus trailing newline, guarded adoption into `blocks.py`, acknowledged checkpoint and actual process termination/relaunch recover that exact text. The next process's Blocks surface offers a new example; no workspace graph restoration is inferred |
58+
| P15 / DR-T13 | Widget/localization/semantics and 2× text coverage is recorded in source validation. Physical native keyboard checks are below. Native XCTest accessibility labels/values are observed; this is not a claim of audible VoiceOver speech or a complete human gesture evaluation |
59+
60+
The offline panel intentionally previews restored text before connection; the
61+
normal Editor shell appears after an explicit board connection. An early final
62+
candidate helper incorrectly expected an Editor text field while still on that
63+
panel. The panel held the exact recovered text; the corrected connected check
64+
passed. That selector error is not a restoration failure.
65+
66+
## Keyboard defects and physical regression
67+
68+
Three separately tested repairs address measured failures: landscape overflow,
69+
native WebView keyboard dismissal, and the iPad input-palette transition.
70+
In the last case UIKit reported an off-screen end frame after **Hide keyboard →
71+
Keyboard → Show Keyboard**, while `keyboardLayoutGuide` reported the actual
72+
498-point occlusion. Private logging established that mismatch; its instrumented
73+
binary is excluded from acceptance and distribution.
74+
75+
The final native guide observer supplies the missing geometry, and Flutter uses
76+
the larger valid platform/native inset without summing them. A remaining input
77+
palette is a real occlusion; hiding the full keyboard does not imply zero inset.
78+
Ending editing returns to ordinary safe-area layout.
79+
80+
| Final `bef67bd` receipt | Actual observation |
3881
|---|---|
39-
| Build | Native XCTest helper builds successfully against the connected physical-device SDK; it operates the separately installed normal app |
40-
| Runner startup | Signed helper starts on the iPad |
41-
| OS authentication | iPadOS displays **Touch ID for “XCTest” — Enable UI Automation** |
42-
| Result | Runner initialization times out after 60 seconds while enabling automation mode; the test body does not run |
43-
| Classification | Operator-access dependency, not a failed PyBLE recovery assertion |
44-
| Required action | Device owner authenticates the iPadOS prompt; retry the retained test and then execute the remaining workflow steps |
82+
| `guide-editor-connected` | Existing exact generated checkpoint restores; C3 Ready; the normal Editor receives native focus |
83+
| `guide-editor-palette` | Full keyboard shown, hidden and shown again through the native palette. Editor text-field height remains 218 points with the full keyboard; console Expand occupies y=478…526 above it. Expand is hittable, hides the actual native keyboard, restores the 555-point normal Editor viewport and preserves exact text. Screenshots and accessibility frames agree |
84+
| `guide-blocks-palette` | Native Blocks field repeats Hide → Show Keyboard; Expand remains hittable, dismisses the keyboard, and retains exact `Hello, PyBLE!`. Cancel closes the field without changing its block; returning to Editor retains the exact generated text |
85+
86+
The final source has 984 passing ordinary tests, including guide geometry,
87+
observer lifecycle and stale-generation coverage. iOS profile compilation and
88+
repository analysis/source gates pass. Automated coverage does not replace the
89+
physical input-palette sequence above.
4590

46-
The owner was asked to authenticate on the device. No passcode or biometric
47-
material was requested, captured or substituted. Raw screenshots and the
48-
`.xcresult` remain in ignored `local/recovery-completion/ipad/`; they are not
49-
public documentation assets.
91+
## App-only board matrix
5092

51-
## Acceptance accounting
93+
Immutable program verification identifies the selected firmware: classic ESP32 uses
94+
published `c8f549ee`; S3, Waveshare S3, C3 and Pico use retained observer
95+
`96497b9`. Exact component hashes and the source-impact assessment are in the
96+
[execution record](00_Execution_Record.md) and
97+
[release readiness](06_Release_Readiness.md). No firmware was reflashed for this
98+
app qualification. Identical relevant runtime/build-driver source does not make
99+
the two firmware artifacts byte-identical.
52100

53-
| Evidence | State after this attempt |
101+
| Row | Physical profile / suffix | Installed app | Result / receipt |
102+
|---|---|---|---|
103+
| Q01 | `esp32-4mb` / 8C9E | `e54a78a` | Pass: ordinary discovery/Ready, named Unicode edit/save, stdout/Finished, tight-loop Run/Stop→Idle, exact clear/Open readback, disconnect/reconnect continuity and recovery/current-target cases. Receipts `classic-*`; helper failures retained below |
104+
| Q03 | `esp32-s3-n16r8` / 5646 | `bef67bd` | Pass: ordinary Ready; owned finite source Save/Run→`424242`/Finished; tight-loop Run/Stop→Idle; true clear/Open exact readback of both files; disconnect/reconnect continuity; acknowledged `loop.py` checkpoint, terminate/relaunch and exact Restore. Receipts `matrix-5646*`; initial failed attempts retained |
105+
| Q05 | `waveshare-esp32-s3-lcd-147b` / DA86 | `bef67bd` | Pass: all common finite-output/Stop/readback/reconnect checks and named checkpoint/relaunch/Restore in one `matrix-da86` run |
106+
| Q07 | `esp32-c3-4mb` / C81A | `01a7ac8` | Pass: ordinary Ready, owned `blocks.py` upload/Hello stdout/Finished, genuine clear/Open readback, tight-loop and print-flood Stop→Idle, connection remains usable, reconnect continuity and subsequent bounded Hello run. `c3-replacement-finite-resume`, completed `c3-readback-stops` assertions, `c3-stop-flood-now`, `c3-final-matrix` |
107+
| Q09 | `rpi-pico2-w` / 3DCB | `bef67bd` | Pass after retained initial disconnect: `matrix-3dcb-retry` completes finite-output/Stop, true clear/Open readback, reconnect continuity and exact named checkpoint/relaunch/Restore |
108+
109+
Earlier rows retain their actual installed identities. Later native/layout
110+
changes do not alter transport, storage or Stop behavior, but final keyboard
111+
checks are separately required. These UI Stop observations establish neither a
112+
fresh C3 firmware qualification nor a sub-500-ms wire-level timing result.
113+
114+
## Retained failures and cleanup
115+
116+
| Observation | Classification / disposition |
54117
|---|---|
55-
| Installed normal candidate, version and signature | Pass, limited to the local Preview identity |
56-
| Foreground launch and five-board discovery | Pass, disconnected discovery only |
57-
| Native storage process termination/reopening | Prior passing seed/verify evidence retained in the platform report |
58-
| DR-T12 normal Blocks-to-Editor checkpoint/relaunch | Not run in this continuation; native UI access pending |
59-
| DR-T14 normal offline Restore and physical current-board consent | Not run in this continuation; native UI access pending |
60-
| Remaining applicable P01–P15 steps | Execute and record actual outcomes after UI authorization; the prepared test is not execution evidence |
61-
| Five-profile iPad release rows | Pending; no qualification inferred from the five scan results |
62-
| M-02 / release admission | Remain pending until mandatory evidence and review are complete |
118+
| XCTest Touch ID authorization timeout | Owner completed the prompt; normal-app native automation subsequently runs. Resolved operator-access dependency |
119+
| Newly installed helper launch denied while offline | Developer-certificate verification occurred before the test body. Retry entered offline mode within one running helper, verified both radios and passed; original radios restored |
120+
| Native helper folder/file selector and terminated-app screenshot errors | Corrected using observed controls and device-screen capture; exact retries retained. No passing result inferred from preparation |
121+
| C3 flood stdout prefix assertion | Existing Hello output preceded flood output in the same console label. Stop immediately returned Idle; retry cleared the console first and passed the intended stdout/Stop/readback/reconnect/bounded-run checks |
122+
| Rapid synthetic typing and initial file-row attempts on S3 | One batched XCTest `print(424242` input produced `print(24242)` and failed the exact oracle before Save. Waiting for the visible keyboard and observing automatic `print()` insertion before injecting digits produced exact text; this is a controlled retry, not a code fix. Source review found no digit-normalization rule; the suspected platform/controller feedback timing was not proven. A further final-candidate control injects the original whole batch after the keyboard is fully visible and settled and passes exact text plus checkpoint/relaunch/Restore (`settled-native-input`); the failure is not reproduced under that controlled focus condition. Two initial file-Open assertions also timed out; explicit retries obtained exact source after a genuine empty Editor, and their failures remain retained |
123+
| Early typing before async New-file GET completed | The editor epoch guard retained the newly typed buffer; no stale GET replaced it. A disposable classic `/untitled.py` was consequently written by the explicit Save/Run; this exact owned file was backed up and removed during coordinated cleanup |
124+
| Initial Pico connection | Reached Ready, then disconnected before folder creation. A continuation incorrectly assumed the old connected layout and selected the Waveshare scan row; its Name-field assertion failed before any write. Waveshare cleanup had already finished. The corrected retry explicitly disconnected, rescanned, checked Pico Ready and passed the complete row; no firmware or transport fix is claimed |
125+
| iPad input-palette geometry | Product defect reproduced with measured native frames; final repair and physical results above |
63126

64-
The [operator recipe](01_Operator_Recipe.md) and
65-
[normative scenario matrix](../../../specifications/App/current-draft-recovery.md#7-required-evidence-before-acceptance)
66-
remain the acceptance authority. This record does not change their requirements.
127+
Only disposable qualification files/folders are written. The classic fixtures
128+
and their CRC-verified backups/cleanup are recorded with the
129+
[Android continuation](05_Android_Acceptance.md); pre-existing root entries are
130+
preserved. The S3, Waveshare and Pico follow-up fixtures have likewise been CRC-verified,
131+
backed up and removed with unrelated root entries unchanged. C3 fixtures remain
132+
tracked privately for cleanup after the final Android continuation. Raw captures, binaries, database backups and helper
133+
sources remain ignored. No user project or original store installation is reset.
134+
135+
This report establishes only its recorded observations. Final admission,
136+
production package identity and channel delivery are tracked in
137+
[release readiness](06_Release_Readiness.md); independent pilot and Ready-program
138+
obligations remain separate.

0 commit comments

Comments
 (0)