From 8825d74fe12653b9f9ab406f75df4a299cd119dd Mon Sep 17 00:00:00 2001 From: Ross Tomsic Date: Mon, 17 Aug 2026 11:40:42 -0400 Subject: [PATCH] Accept alpha.8 isolated execution --- README.md | 22 ++--- docs/BACKLOG.md | 39 +++++++- docs/HISTORY.md | 10 ++ docs/STATUS.md | 27 ++++-- docs/development/release-signing.md | 13 +++ ...17-alpha8-isolated-execution-acceptance.md | 94 +++++++++++++++++++ docs/investigations/README.md | 1 + 7 files changed, 183 insertions(+), 23 deletions(-) create mode 100644 docs/investigations/2026-08-17-alpha8-isolated-execution-acceptance.md diff --git a/README.md b/README.md index 8b46e11..db2c1b4 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,20 @@ like responses, while a real terminal remains underneath for interactive work. ## Alpha status **[Phase 5: Alpha polish](docs/STATUS.md) is in progress.** Its feature slices -and owner-device acceptance through alpha.7 are complete. Alpha.5 installed in +and owner-device acceptance through alpha.8 are complete. Alpha.5 installed in place but is rejected because a release-shrinker failure prevents SSH connection. Alpha.6 corrects that failure and has passed independent CI, permanent signing, in-place update, and physical acceptance. Alpha.7 adds local -drafting while a command runs and retained-session Home navigation. The -remaining product boundary is invited technical-alpha use sufficient to -evaluate whether ten real users can complete small remote tasks for two weeks -and provide useful feedback. - -The current accepted signed build is `0.1.0-alpha.7`; the current source -candidate is `0.1.0-alpha.8`. Alpha.5 is an immutable rejected artifact. -Alpha.8 adds isolated child-Bash execution for script-like commands so a strict -mode failure does not close the persistent SSH shell. Owner-device acceptance -is pending. +drafting while a command runs and retained-session Home navigation. Alpha.8 +adds isolated child-Bash execution for script-like commands so a strict-mode +failure does not close the persistent SSH shell. The remaining product boundary +is invited technical-alpha use sufficient to evaluate whether ten real users +can complete small remote tasks for two weeks and provide useful feedback. + +The current accepted signed build and source version are both +`0.1.0-alpha.8`. Alpha.5 is an immutable rejected artifact. On the owner's +Galaxy S25 Ultra, an isolated strict-mode failure returned exit 1, preserved the +persistent shell's state, and allowed the next persistent command to succeed. Signed builds are shared directly with invited testers. There is no public signed APK or GitHub prerelease while Phase 5 is open. Testers should obtain the APK and its checksum from the owner through the agreed diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index fac9288..6215869 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -49,6 +49,24 @@ selection, styled spans, web-link confirmation, TalkBack traversal, and the exact bounded-tail contract intact rather than optimizing only the common visual case. +## Transcript viewport with the software keyboard + +**Status:** Deferred functional UX bug; alpha.8 command execution remains +usable, but normal transcript work requires avoidable recovery scrolling. + +On the Galaxy S25 Ultra, focusing the transcript composer and sending commands +with the software keyboard open moved the useful transcript content above the +visible viewport. The composer remained usable and commands completed, but the +user had to scroll back up to recover the new cards and output. Connection, +execution, and data remained intact. The recovery scrolling is repeated +friction in the primary interaction path. + +When this is fixed, test focus, submission, running output, completion, +tail-following, manual user scrolling, keyboard dismissal, rotation, and large +font sizes together. The current or newly completed turn should remain easy to +reach while the composer stays usable. Do not force-scroll a user who has +deliberately moved into older output. + ## Responsive onboarding and edge-to-edge polish **Status:** Deferred visual and responsive-layout polish; monitor action @@ -115,8 +133,8 @@ made that execution contract unambiguous. ## Persistent-shell exit recovery -**Status:** Isolated execution implemented in post-alpha.7 source; automatic -shell restart remains deferred. +**Status:** Isolated execution implemented and physically accepted in alpha.8; +automatic shell restart remains deferred. Transcript Send intentionally evaluates inside the persistent Bash shell so directory changes, exports, aliases, and functions survive between cards. That @@ -130,6 +148,11 @@ warning, isolated cards are labeled, and reruns preserve their execution mode. The mode is also retained in saved transcript history. Persistent Send remains available because changing live shell state is sometimes intentional. +The permanent-key alpha.8 build passed the physical fixture boundary: an +isolated strict failure reported exit 1, did not run the command after `false`, +did not leak its directory or exported-variable changes, and left the original +persistent state available to the next successful command. + A later recovery slice may retain the transcript and offer a fresh shell when the persistent shell itself exits. It must say that shell state was lost. Do not imply that a restarted shell preserved a directory, variable, function, or @@ -182,6 +205,12 @@ but the archive presentation is deliberately utilitarian. A later design pass may improve session summaries, command-card hierarchy, navigation, search, and the distinction between live styled output and persisted plain text. +Alpha.8 exposed one concrete omission: Room retains whether a command ran +isolated, but the saved-transcript dialog formats only status and exit code. An +isolated failed turn therefore appears as `Failed · exit 1` without its +execution contract. Add the execution-mode label to saved cards when history +presentation is revised, and cover it with a UI test. + Preserve bounded retention, explicit deletion, no-write ephemeral sessions, and the rule that history must not accidentally become credential storage. @@ -286,7 +315,7 @@ content, host data, or terminal output merely to claim that metrics exist. ## Automated release-path and device acceptance **Status:** Deferred test-infrastructure design; manual physical acceptance -through alpha.7 is complete. +through alpha.8 is complete. The core debug Android suite and static release-shrinker checks run in public CI, but alpha.5 showed the remaining gap: assembling a minified APK is not the same @@ -299,6 +328,10 @@ then completed manual drafting and retained-session Home acceptance on the physical device. Automating those signed release paths remains future test infrastructure work. +Alpha.8 used the same path, then manually proved isolated strict failure, +state containment, saved transcript recovery, and a successful persistent +follow-up without reconnecting on the physical device. + A later automation slice should define how to cover a packaged minified app through fixture connection, password and imported-key authentication, structured commands, raw-terminal input, same-session switching, and retained diff --git a/docs/HISTORY.md b/docs/HISTORY.md index ecb1757..260520c 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -93,6 +93,16 @@ the Galaxy S25 Ultra. The retained-session Home and Return path passed. During a running `sleep 10`, the composer accepted a `pwd` draft while Send remained disabled; Send enabled when the shell returned to ready and the draft executed normally. This made alpha.7 the accepted tester build. + +Alpha.8 then added an explicit child-Bash execution path for script-like input +while retaining persistent Send for state-carrying commands. The merged-main +candidate passed CI and permanent signing, then installed on the Galaxy S25 +Ultra. A physical fixture run proved that an isolated `set -euo pipefail` block +returned exit 1 without its unreachable line, kept child directory and export +changes out of the persistent shell, and allowed the next persistent command to +succeed with its original state. Alpha.8 became the accepted tester build. The +same run exposed deferred transcript keyboard anchoring and saved-history mode +label issues without invalidating command execution. Additional device and OEM coverage is opportunistic alpha evidence rather than a separate Pixel gate. See [STATUS.md](STATUS.md) rather than this chronology for the active boundary. diff --git a/docs/STATUS.md b/docs/STATUS.md index e03b2d1..ea60784 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -105,10 +105,10 @@ terminal correctly remained terminal-only rather than creating transcript cards. See the [alpha.6 Ed25519 shrinker correction](investigations/2026-08-10-alpha6-ed25519-shrinker-correction.md). -Product work continues while invited alpha use is gathered. The current accepted -tester build is `0.1.0-alpha.7` (`10007`). Its first slice keeps the structured composer -editable while a command runs, preserves that local draft through -same-session terminal switching and Android saved-state restoration, and keeps +Product work continues while invited alpha use is gathered. Alpha.7's first +slice keeps the structured composer editable while a command runs, preserves +that local draft through same-session terminal switching and Android +saved-state restoration, and keeps Send disabled until the shell returns to ready. It does not queue or automatically execute commands. Its second slice adds a Home route that retains the one active SSH session, shows that session with explicit Return and @@ -122,16 +122,25 @@ Galaxy S25 Ultra, and passed the retained-session Home and Return path. While a disabled. Send enabled when the shell returned to ready, and the draft then ran normally. This completes alpha.7 owner-device acceptance. -The current source candidate is `0.1.0-alpha.8` (`10008`). It adds an explicit -isolated execution path for script-like commands. It runs the exact composer -text in a child Bash process, +The current accepted tester build and source version are both +`0.1.0-alpha.8` (`10008`). It adds an explicit isolated execution path for +script-like commands. It runs the exact composer text in a child Bash process, reports the child exit status in the normal command card, and leaves the persistent shell available after strict-mode failures. Persistent Send remains the state-carrying path. Common `set -e`, `set -u`, and long-form strict-option prologues produce an advisory warning; isolated cards and saved history retain their execution mode. Host-side Bash regression, JVM, Compose, Room migration, -and fixture-backed production SSH tests cover the new boundary. Owner-device -acceptance remains pending for the next signed candidate. +and fixture-backed production SSH tests cover the new boundary. + +The exact merged-main candidate passed CI, permanent signing, checksum, +certificate, v2/v3 signature, package identity, and 16 KiB alignment checks. +Android installed it on the Galaxy S25 Ultra. Against the real fixture, a +persistent command established an exported marker and `/tmp` working directory. +An isolated strict block changed both values inside the child, printed those +child values, stopped at `false` with exit 1, and omitted its unreachable line. +The next persistent command returned the original marker and `/tmp`, with exit +0 and without reconnecting. This closes alpha.8 owner-device acceptance. See the +[alpha.8 isolated-execution investigation](investigations/2026-08-17-alpha8-isolated-execution-acceptance.md). ## Remaining Phase 5 boundaries diff --git a/docs/development/release-signing.md b/docs/development/release-signing.md index a634f6a..1ceb224 100644 --- a/docs/development/release-signing.md +++ b/docs/development/release-signing.md @@ -96,6 +96,19 @@ retained-session Home slices passed on the physical device. See [`STATUS.md`](../STATUS.md) for the current accepted build; preserve the exact alpha.6 facts above as release-history evidence. +Permanent-key alpha.8 uses the same certificate. Its verified APK SHA-256 is: + +```text +5389284c490e8323943f4cac324713928401ad2836f3cfee3b904827e5cafcec +``` + +The artifact identifies as `io.github.r055le.threadline`, version +`0.1.0-alpha.8` (`10008`), verifies with APK signature schemes v2 and v3, and +is 16 KiB page aligned. Its exact merged-main candidate passed public CI and +was selected through `scripts/sign-latest-alpha.sh`. Android installed it on +the Galaxy S25 Ultra, where isolated strict failure, state containment, and +persistent-command recovery passed against the disposable fixture. + ## Signing-key boundary The long-lived release keystore and its passwords must never enter this diff --git a/docs/investigations/2026-08-17-alpha8-isolated-execution-acceptance.md b/docs/investigations/2026-08-17-alpha8-isolated-execution-acceptance.md new file mode 100644 index 0000000..e552ea0 --- /dev/null +++ b/docs/investigations/2026-08-17-alpha8-isolated-execution-acceptance.md @@ -0,0 +1,94 @@ +# Alpha.8 isolated execution acceptance (2026-08-17) + +## Result + +`0.1.0-alpha.8` (`10008`) is the current accepted tester build. Its permanent +APK passed artifact verification, installed on the Galaxy S25 Ultra, connected +to the disposable OpenSSH fixture, and completed the owner-device isolated +execution boundary. + +An isolated strict-mode failure returned the child process's real exit status, +did not run the following statement, did not alter persistent shell state, and +left that shell ready for the next command. This closes the physical acceptance +left open when the source implementation merged. + +## Candidate provenance and verification + +The candidate came from merged `main` commit `3f9e27a`, built by the successful +public Android workflow run `32041513591`. GitHub returned a transient 502 while +the runner fetched a pinned action, then backed off and retried successfully. +The full job completed, including JVM tests, lint, debug and minified release +assembly, shrinker-contract checks, the API 35 instrumented suite, candidate +packaging, and artifact upload. + +The local signing helper selected that exact source-identified CI candidate and +used the off-repository permanent key. Independent checks reported: + +- package: `io.github.r055le.threadline` +- version: `0.1.0-alpha.8` (`10008`) +- APK SHA-256: + `5389284c490e8323943f4cac324713928401ad2836f3cfee3b904827e5cafcec` +- signing-certificate SHA-256: + `102893bcc2fa4b70fb451661579c717c6c2b917296a99baefa6d9e9d1d13e7fc` +- signer: one 4096-bit RSA key with certificate subject `CN=Threadline` +- APK signature schemes: v2 and v3 verified +- 16 KiB page alignment: verified + +The certificate matches the permanent update lineage. The signing key, +passwords, fixture credential, private endpoint, and fixture identity did not +enter the repository or this record. + +## Physical execution proof + +The signed app connected from the Galaxy S25 Ultra running Android 16 / One UI +8.5 to the real fixture through a temporary private tunnel. + +First, persistent Send established state: + +```bash +cd /tmp && export THREADLINE_ALPHA8_MARKER=parent +``` + +The card succeeded with exit 0. The next multiline command used **Run +isolated**: + +```bash +set -euo pipefail +export THREADLINE_ALPHA8_MARKER=child +cd / +printf 'isolated:%s:%s\n' "$THREADLINE_ALPHA8_MARKER" "$PWD" +false +printf 'unreachable\n' +``` + +The card printed `isolated:child:/`, failed with exit 1, and did not print +`unreachable`. A following persistent command then ran in the same connection: + +```bash +printf 'persistent:%s:%s\n' "$THREADLINE_ALPHA8_MARKER" "$PWD" +``` + +It printed `persistent:parent:/tmp` and succeeded with exit 0. Together these +observations prove that the isolated child inherited the starting shell state, +contained its own changes and strict failure, and returned control to the +original persistent shell. + +The saved transcript recovered all three commands, their output, and exit +statuses after the session. This adds physical evidence to the existing Room +migration and persistence tests. + +## UX findings kept separate + +Two findings do not invalidate the execution boundary: + +1. With the software keyboard open, transcript submission can move the useful + command cards and output above the visible viewport. The composer and + execution remain functional, but the user must scroll back up after sending. +2. The saved transcript retains the isolated execution mode in Room, but its + dialog formats only command status and exit code. The isolated card therefore + appears as `Failed · exit 1` instead of visibly including `Isolated`. + +Both are recorded in `docs/BACKLOG.md`. The first belongs to IME and transcript +scroll coordination. The second is a narrow history-presentation omission. +Neither should be confused with loss of output, a dropped session, or incorrect +shell semantics. diff --git a/docs/investigations/README.md b/docs/investigations/README.md index 36e51e1..1588a9d 100644 --- a/docs/investigations/README.md +++ b/docs/investigations/README.md @@ -34,3 +34,4 @@ technical claim. | 2026-08-09 | 5 | [Alpha.4 installed-update preservation](2026-08-09-alpha4-update-preservation.md) | public-CI candidate provenance, permanent-key update, retained local state, and imported-key auth without re-import | | 2026-08-10 | 5 | [Alpha.5 signing and release-shrinker rejection](2026-08-10-alpha5-signing-update-progress.md) | resumable signing proof, physical connection failure, minified reproduction, and cbssh Ed25519 provider root cause | | 2026-08-10 | 5 | [Alpha.6 Ed25519 shrinker correction](2026-08-10-alpha6-ed25519-shrinker-correction.md) | narrow provider keep rule, mapping/DEX regression gate, permanent artifact, and physical acceptance | +| 2026-08-17 | 5 | [Alpha.8 isolated execution acceptance](2026-08-17-alpha8-isolated-execution-acceptance.md) | permanent artifact, strict failure containment, persistent state recovery, and physical UX findings |