Skip to content

feat(chat): navigate previous and next message starts - #215

Draft
omgoshjosh wants to merge 4 commits into
dzianisv:mainfrom
omgoshjosh:feat/214-message-navigation
Draft

omgoshjosh wants to merge 4 commits into
dzianisv:mainfrom
omgoshjosh:feat/214-message-navigation

Conversation

@omgoshjosh

@omgoshjosh omgoshjosh commented Oct 1, 2026 •

Copy link
Copy Markdown

Closes #214

Current Source / Artifact

Source155e0ba6172c87de92fea0e40861187e3b037595; tree02283e216ab4e2cbc8c66bb9ed6a49a8d1875d6c.352sourcechecks,typecheck,version0.4.15/42,diffPASS. Viewport-top Previous/Next above double-caret Latest; Android physical-right gutter corrected through logical-left76. No controller/composer/native-policy changes in latest gutter fix.

Exact-source isolated build receipt: navigation214155e0baAPK SHA2566981bc2abbbf7a4af3ead5533daa470fd9aa9c69c4a957f5cf3b7a1d8cf2f4dd, releasearm64,0.4.15/code42. Production/.eval untouched.

Actual Native Result

Independent UI report: keyboard-CLOSED gutterPASS bubblex36..837/controlx873..972=36pxgap. Keyboard-OPEN composer/sendFAIL: focusedQAKeyboardDraft input[189,1476][873,1570],send[891,1480][981,1570] visually obscured. Navigation/append NOTRUN after firstblocker, notpass/fail. Ownedcleanup verified PID45810absent/13022free/reverseempty/broker0nodrift.

Read-only attribution found no concrete feature-local vertical cause; root/native/keyboard/composer policy unchanged against EXACTbaseline646f9cbf7743e08115c8121d98c82f48d088a8f4. Static equality is not runtime equivalence; baseline-only attribution NOT established. OldbottomlabeljumpWITHDRAWN; historical17claims/earlierAPKs remain separately pinned.

Authorized Diagnostic Boundary

One isolated exactbaseline646f9cb build (if no known pinned artifact), then SAMEQA four matched baseline-first CLOSED/OPEN and existingfeature CLOSED/OPEN captures is authorized. Native package/signer/SDK/window/edge-to-edge/build envelope must match; feature restored and owned resources/temporary worktree cleaned. No speculativepatch, secondbaseline/featurebuild, broadQA/fixturesextension/retry. Comparison RESULTS PENDING, not acceptance or generic human-approval blocker.

Publication Limits

Draft; no upload/distribution/upstreammerge/tag/store/CUAwaiver. AGENTS185-191CUAunwaived; tester-onlymanualpolicy/AppTesterroute separatepending. Upstreamaction_required/jobs[]notgreen. Sharedkeyboardfix/IME208scope notauthorized by diagnostic experiment; Yondi/CIreviewer leftalone.

@omgoshjosh

Copy link
Copy Markdown
Author

Manager update at head 50f747b: independent graph QA rejects UX approval for controls obscuring response text (app/session/[id].tsx:767-779,949-954; committed screenshots). Earlier implementation-associated static-UX PASS is not final approval. Existing QA work is continuing native/manual rapid-tap, streaming/appends and constrained keyboard checks; no feature edits or merge.

Azure is not a blanket deployment prerequisite. AGENTS.md:185-191 mandates CUA before merge/release, not Azure specifically; no CUA pass or waiver claimed. Tester-only physical/manual acceptance may be proposed once evidence and actual App Tester route are established. Existing build/348 tests/17 device fixture jumps retain their documented attribution. No distribution, tag or store upload performed.

@omgoshjosh

Copy link
Copy Markdown
Author

UX remediation pushed: 419bece (fix(chat): reserve message navigation gutter (#214)).

Scope: only app/session/[id].tsx and a new source-level layout regression. Message content now reserves a 76-point right gutter (44-point control width + 16-point inset + 16-point text gap), retaining the existing controls and hit targets. No native keyboard/IME, navigation controller, backend, release metadata, QA evidence, or retained APK changes.

Source gates: 349 tests passed, zero failures; npm run typecheck, npm run check:versions (0.4.15 / 42), and diff whitespace checks passed. Working tree is clean.

QA handoff: this changed head still requires independent code/behavior/UX review and physical keyboard/layout acceptance, including long messages, constrained keyboard viewport, Previous/Next/Latest, manual reanchoring, composer draft/focus, and virtualization. Existing screenshots and retained APK remain pinned to original head 50f747b; those results are NOT evidence for this changed head. No replacement build or device work was started while original-artifact QA uses the retained build.

PR remains draft. Mandatory CUA before merge/release remains unwaived; no merge or release readiness is claimed.

@omgoshjosh

Copy link
Copy Markdown
Author

Issue 214 Isolated Build Receipt

BUILD SOURCE: 419beced720a529e7753743453127aad7968b6a6.
PR #215 head independently verified before and after: same source SHA; draft.
Git tree: 56917f86bbdad113de759f18a31b8d3fa70753ce.
Source dirty state: clean before build; no tracked/source changes after build.
After-build porcelain status: ?? docs/qa/issue-214-build-419beced/ only.
Evidence is not committed or pushed; no feature/native/IME/backend edits.

Evidence directory (absolute):
/Users/josh/agents/worktrees/mobile-message-navigation-214/docs/qa/issue-214-build-419beced.

Build started UTC 2026-10-01T21:32:55.955Z; ended UTC 2026-10-01T21:33:26.538Z.
Actual lease/Gradle exit code: 0. Gradle reports BUILD SUCCESSFUL in 28s.
Working directory: /Users/josh/agents/worktrees/mobile-message-navigation-214/android.

/Users/josh/agents/bin/lease run --owner ses_f0aaeaf99ffedwO7e5cr1OKoyB --project mobile --priority experiment --ttl 1800 android-build -- ./gradlew assembleRelease -PreactNativeArchitectures=arm64-v8a --max-workers=2 --console=plain --no-build-cache --init-script /var/folders/fc/xccpf99d62b5_sc13zpgvjd80000gn/T/opencode/issue-214-419beced.init.gradle

Safe environment overrides: ANDROID_HOME and ANDROID_SDK_ROOT point to
/Users/josh/Library/Android/sdk; JAVA_HOME points to
/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home;
SENTRY_DISABLE_AUTO_UPLOAD=true, EXPO_NO_DOTENV=1.
Release signing environment variables were omitted; existing ignored development
keystore was used. Full environment names, not secret values, are in the receipt.

receipt.json includes before/after tracked-file SHA256 maps, exact override
path/content/hash, environment names, command, exit, actual manifest and signer.
SHA256: c5b7fb219a2de5c7014acd80df99536f7e1afefb16009705fcf8fa1700170ecd.

build.log SHA256:
f4a93ae21b361a1d4709e47c5b3fa5d365ec1c00fc4f208ed0e7cd5e0992ed18.

navigation214-419beced-arm64-release.apk SHA256:
4a01f376557e96f9a2b37a87b1dc463b9f5aaf111635febd29827019e73e7682.

Actual APK manifest: package cc.agentlabs.opencode.navigation214,
versionName 0.4.15, versionCode 42, native ABI arm64-v8a.
Verified development signer certificate SHA256:
0b9c1685876036903653decbd84840474ff09db07fe8958e846443b2ee5c1fae.

Fresh bundle proof: log lines 1560-1566 show the bundle task executing (not
UP-TO-DATE or FROM-CACHE), Metro bundling 2508 modules and writing bundle output.
External init forces this task out of up-to-date checks; build cache disabled.
Extracted APK index.android.bundle SHA256:
4187eef17221cfd07abc7d6a65cbd0b638ff6040a434ad1347526413524b9f43.
Override SHA256:
da7149ff5a3da877b8da76dccfa431b4caafb9e5d4537e67e00cc46f7fafd162.

Historical prebuild APK was preserved as historical-prebuild.apk, with SHA256
462db5c372931ba62432f74decd32c2957166d26522650e7babf71f6c238bc56.
It and the old 17 fixture jumps are HISTORICAL ONLY, not this build's runtime evidence.

Previously recorded source-only gates for 419bece: 349 tests, zero failures;
typecheck, version parity and diff checks passed. Source did not change during
this build, so these checks were not rerun or represented as native acceptance.
Postbuild diff check passed; broker reports zero leases and no device drift.

Native/UX validation belongs to SAME QA ses_f06bab859ffeE0daJWiGLS5nSm next.
No device install or test was performed by this build session. No production or
.eval package was changed. Mandatory CUA before merge/release remains unwaived;
no merge/release/distribution readiness is claimed. App Tester/manual substitute
decisions are separate and did not block this executable build.

@omgoshjosh

Copy link
Copy Markdown
Author

Current419beced exact-build QA milestone: APK4a01f376557e96f9a2b37a87b1dc463b9f5aaf111635febd29827019e73e7682 installed on Pixel8Pro under lease, production/.eval untouched;349sourcechecksPASS. Full14:50report provides partial cold-history navigation/manual/Latest checks, not native approval. Current17taps/screenshotUser16 is not17 independently asserted starts; old50f74717jump evidence stays historical.

Composer was obscured with keyboard; an initial SSE-updated view jumped unexpectedly before cold restart. Append outcome, native rapid taps and detailed geometry remain incomplete, not automatically product defects or passes. SameQA resumed bounded checks/owned fixture cleanup; same engineer resumed source diagnosis and fixes ONLY confirmed feature regressions, excluding IME208. No duplicate workers/custom harness/infra, no upload/merge/tag/release. AppTester route/manual acceptance separate pending; no Azure prerequisite imposed.

@omgoshjosh

Copy link
Copy Markdown
Author

Bounded source diagnosis, SAME engineer ses_f0aaeaf99ffedwO7e5cr1OKoyB: source remains 419bece, no tracked changes. Existing untracked build/QA evidence preserved. No build/device/fixture activity or modifications to active QA evidence.

No reproducible feature defect established in this bounded review. Existing navigation regressions: 15/15 passed using node --experimental-strip-types --test src/lib/message-navigation.test.ts. Existing SSE merge regressions: 6/6 passed using node --experimental-strip-types --test src/lib/message-merge.test.ts. Diff check passed. Previously recorded full349 gates remain separately attributed; not rerun because source unchanged.

Source findings (hypotheses, NOT proven causes of the native jump):

  • src/lib/message-navigation.ts:11-17 retains frames for surviving message IDs across sync; app/session/[id].tsx:215-218 refreshes frames on native onLayout. Streaming growth/appends can temporarily leave surviving coordinates stale until layout callbacks arrive. Existing growth regression supplies refreshed frames explicitly (message-navigation.test.ts:59-68), so it does not prove native layout/scroll ordering. A concrete failing event sequence or reproducible native jump is needed before choosing invalidation behavior; indiscriminate clearing could break virtualization and pending seeks.
  • message-navigation.ts:20-23 uses a pending target/completed anchor before viewport inference. observe():61-66 invalidates completed anchors on changed offset/height, not a frame-only update. This is a candidate to inspect if the jump repeats after growth without a scroll event, not proof that it happened.
  • src/lib/message-merge.ts:18-31 updates existing IDs in place and appends unseen IDs; the screen reverses this arrival-order list (app/session/[id].tsx:188-201). Replaying/seeding unseen historical messages out of chronological order can yield different warm vs cold history order. Standard fixture prompt writes user then assistant in append order (tests/fixtures/mock-opencode-server.ts:343-400); that path alone does not establish a fixture ordering defect. Actual prior seed/event order remains UNKNOWN, so no fixture blame or store patch is justified.

Manager-reported current APK evidence remains partial: cold history Previous/Next/manual reanchor/Latest worked; a 17-tap endpoint screenshot is NOT seventeen independently asserted starts; one warm SSE jump and sent-draft append remain unconfirmed. Composer baseline attribution remains UNKNOWN; no keyboard/native or IME208 changes authorized/performed.

Current isolated APK remains pinned to source419beced: SHA256 4a01f376557e96f9a2b37a87b1dc463b9f5aaf111635febd29827019e73e7682. Receipt docs/qa/issue-214-build-419beced/receipt.json SHA256 c5b7fb219a2de5c7014acd80df99536f7e1afefb16009705fcf8fa1700170ecd; build.log SHA256 f4a93ae21b361a1d4709e47c5b3fa5d365ec1c00fc4f208ed0e7cd5e0992ed18. No new build was warranted or performed.

Precise next step: SAME QA completes its already-active bounded native run and hands off any repeatable jump with ordered message IDs, pre-tap viewport/start, update/gesture sequence, expected adjacent target and actual landing. Engineer is available at the turn boundary for that handoff, without readiness polling/wait loops. Only an established scoped defect will trigger a minimal feature/test fix and new-head validation. No full native acceptance, CUA waiver, merge/release/distribution claim.

@omgoshjosh

Copy link
Copy Markdown
Author

Exact-head physical QA update

Validated source 419beced720a529e7753743453127aad7968b6a6 on a Pixel 8 Pro using isolated APK SHA-256 4a01f376557e96f9a2b37a87b1dc463b9f5aaf111635febd29827019e73e7682. Production and .eval packages were left untouched. Previously recorded source gates (349 tests, typecheck, version check, diff check) remain passed; no source changed.

Passed: Cold-loaded Previous/Next message starts; manual-scroll reanchor; Latest to line 70; oldest User Message 1 boundary/no-op; 16 counted Previous actions reaching User Message 19; one live fixture SSE append while anchored, followed by Latest and Previous to User Message 26; app-submitted DraftQA214 plus mock reply delivered over SSE. Native accessibility bounds measured each control at 99x99 device pixels (44 dp at 360 dpi). The list reserves a 76 dp right gutter; long reply text remained visibly clear of controls.

Failed: Live-updated history did not always select the adjacent message. After 25 prompt/reply pairs arrived over SSE while the app stayed open, Previous from the latest view landed on User Message 1; after force-stopping only the isolated package and reopening the same server-backed session, Previous landed on User Message 25. In a separate three-prompt SSE burst, three rapid Previous taps from Latest landed at Burst Message 2 instead of Burst Message 3; after reset and settled taps the same three-step sequence reached Burst Message 3. Exact screenshots and fixture ordering are retained in the QA artifact directory; this is current-head evidence, not the historical APK result. The same-head navigation discrepancy has been sent to the existing engineer for investigation.

Partial / incomplete: Keyboard stayed open and the draft survived navigation, but the composer was obscured by the IME. Baseline attribution is unknown; no IME #208 change is proposed. Existing fixture checks validate mock protocol SSE only, not live backend/AI or incremental token streaming. Mandatory vision CUA remains incomplete and unwaived. Merge/release readiness is not claimed.

@omgoshjosh

Copy link
Copy Markdown
Author

SAME engineer outcome: scoped navigation callback-order regression fixed and pushed to SAME draft PR215.

New source/verified PR head: a550126; git tree 2e68e9a70a19421298ca55532ba9b519b5815711. Commit: fix(chat): retain navigation intent across delayed scroll events (#214). Tracked checkout clean afterward; only preserved untracked docs/qa/issue-214-build-419beced evidence. Staged/committed ONLY app/session/[id].tsx, src/lib/message-navigation.ts and its test. No native/IME208/backend/store/fixture edits, no evidence commits/push.

Established code defect: existing controller completed a tap before its native scroll callback; an older callback arriving after the next tap invalidated the newer anchor and selected a non-adjacent boundary. Added repo-pattern regression FAILED on pre-fix controller (expected third index3, actual2) and PASSED after fix. The six-row test uses burst order reply3/reply2/reply1/user3/user2/user1. This establishes a callback-order bug, not literal reproduction of every screenshot landing.

Fix: remember the commanded offset and retain logical intent until native observation acknowledges it; manual drag or viewport resize cancels that guard, and subsequent acknowledged scrolling resumes viewport reanchoring. Latest now resets logical offset to0 immediately rather than waiting for native animation callbacks. Three new regressions cover delayed offsets, Latest with an older queued callback, and acknowledged/manual reanchoring. Existing growth, resize, virtualized seeking, clamped short-row, removal and bounds tests remain passing.

Gates rerun after source change: npm test 352/352 pass, zero failures (18 navigation tests); npm run typecheck pass; npm run check:versions pass 0.4.15/code42; git diff --check and cached diff check pass. Full test output /Users/josh/.local/share/opencode/tool-output/tool_0fa98bf6c001E83mRRDb6C1HDJ.

Bulk SSE vs cold-history jump remains requiring actual-device revalidation; its specific root cause is NOT proven. No stale-frame invalidation or fixture ordering changes made. Composer visibility baseline attribution UNKNOWN and outside scope. Source tests are not native UX acceptance.

BUILD/HANDOFF DEFERRED: one oxm ready check before rebuilding returned SAME QA ses_f06bab859ffeE0daJWiGLS5nSm BUSY (exec=running, no children). No polling/retry, duplicate build/device work, replacement artifact, or artifact relabel. Disk checked42.5GB free, no resource blocker. Existing APK4a01f376557e96f9a2b37a87b1dc463b9f5aaf111635febd29827019e73e7682 and receipt c5b7fb219a2de5c7014acd80df99536f7e1afefb16009705fcf8fa1700170ecd remain pinned ONLY to419beced and are now historical relative to a550126; not new-source evidence.

Precise next step after SAME QA old-artifact turn completes: resume this SAME engineer for one readiness check and broker-leased isolated navigation214 build using the established external finalizeDsl override, fresh bundle, and separate docs/qa/issue-214-build-a550126 exact-head receipt/log/APK. Then hand fresh provenance directly to SAME QA for independent rapid-burst and warm bulk-SSE/cold-history comparison plus full native regression/UX review. No native success, CUA waiver, merge/release/store/distribution claim.

@omgoshjosh

Copy link
Copy Markdown
Author

Issue 214: a550126 Isolated Build

BUILD SOURCE and verified before/after PR215 head:
a5501268386a8288440ab842fd7f5c5fc3df7ef2.
Tree: 2e68e9a70a19421298ca55532ba9b519b5815711.
Tracked source clean before/after; before untracked status only
docs/qa/issue-214-build-419beced/, afterward also this evidence directory.
No source/native/IME/backend changes; evidence remains uncommitted/unpushed.

Evidence directory:
/Users/josh/agents/worktrees/mobile-message-navigation-214/docs/qa/issue-214-build-a550126.

Build UTC start 2026-10-02T03:17:07.369Z, end 2026-10-02T03:17:38.715Z.
Lease/Gradle exit 0; BUILD SUCCESSFUL in 28s.
Command working directory: worktree android/.

/Users/josh/agents/bin/lease run --owner ses_f0aaeaf99ffedwO7e5cr1OKoyB --project mobile --priority experiment --ttl 1800 android-build -- ./gradlew assembleRelease -PreactNativeArchitectures=arm64-v8a --max-workers=2 --console=plain --no-build-cache --init-script /var/folders/fc/xccpf99d62b5_sc13zpgvjd80000gn/T/opencode/issue-214-419beced.init.gradle

The reused external init filename is historical; its head-independent content
uses androidComponents.finalizeDsl to override application ID and development
signing, and forces fresh release bundling. No tracked native configuration was
changed. Init content/path/hash are captured in the new receipt.
Override SHA256: da7149ff5a3da877b8da76dccfa431b4caafb9e5d4537e67e00cc46f7fafd162.

Safe environment: Android SDK /Users/josh/Library/Android/sdk; JDK
/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home;
SENTRY_DISABLE_AUTO_UPLOAD=true, EXPO_NO_DOTENV=1, release signing variables
omitted. Full environment names without secret values are in receipt.json.

SHA256 provenance:

File SHA256
receipt.json 5766496d2e1adce52e67dfe1f4c6084e4d3c9af1cc41594086ade4a4bc8937cc
build.log fca183e2dbe425ac4bd536feefa75d9096d7fc846630698c8fa6aa12f204ebd2
navigation214-a550126-arm64-release.apk 7b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666
index.android.bundle (extracted from APK) b5ce17ce06cc99205bace2b23060bafb1e616c97e5b257be74716d122b9e536e

Log lines 1560-1567 show the bundle task executed (not UP-TO-DATE/FROM-CACHE),
Metro bundled 2508 modules, and bundle output was written.
Actual APK manifest: cc.agentlabs.opencode.navigation214, versionName
0.4.15, versionCode 42, ABI arm64-v8a.
Verified signer certificate SHA256:
0b9c1685876036903653decbd84840474ff09db07fe8958e846443b2ee5c1fae.
Receipt includes actual manifest/signature and before/after tracked-file hashes.

Previously rerun a550126 source gates: 352 tests passed, typecheck/version/diff
checks passed. No further source change; suite not rerun during build. Postbuild
diff check passed. Disk checked 42.5GB free; lease released, zero leases/no drift.

419bece APK/receipt/physical QA are preserved untouched under the old evidence
directory and HISTORICAL ONLY relative to this source. Old APK SHA256
4a01f376557e96f9a2b37a87b1dc463b9f5aaf111635febd29827019e73e7682.

No device work performed by engineer. SAME QA returned READY on the single
postbuild check. New-source rapid-tap fix is source-tested, NOT native accepted;
warm bulk-SSE vs cold-history discrepancy's specific cause remains UNPROVEN.
Independent provenance/native callback ordering and complete regression/UX
matrix are required on this new artifact. Composer baseline UNKNOWN, IME208
excluded. Fixture SSE is not live AI/backend or incremental-token proof.
Mandatory CUA unwaived; no merge/release/tester upload/distribution claim.

@omgoshjosh

Copy link
Copy Markdown
Author

Exact-head physical QA on a550126 used isolated APK SHA-256 7b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666 on Pixel 8 Pro. 25 correctly ordered fixture SSE pairs arrived live while app stayed open. Latest showed User 25; one settled Previous attempt landed at User 23 (unexpected), while a reset/repeat and Next→Previous returned User 25. Three rapid Previous actions ended at User 24 as expected. This is an intermittent native failure, so navigation is not accepted. An overly-fast unpaired stimulus was excluded. Evidence and limits are recorded locally in docs/qa/issue-214-build-a550126/PHYSICAL-QA.md. Mock short replies only; live AI/streaming, full UX matrix, and mandatory CUA remain incomplete/unwaived. No merge/release/upload.

@omgoshjosh

Copy link
Copy Markdown
Author

Bounded SAME engineer diagnosis: source remains a550126; exact APK SHA2567b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666. No tracked edits, tests added, commit/push, rebuild, device/fixture activity, worker, polling, or changes to preserved untracked evidence. SAME QA final-report turn left uninterrupted. Existing352 gates are unchanged, not rerun.

Read FULL docs/qa/issue-214-build-a550126/PHYSICAL-QA.md, relevant screenshots, extracted native XML bounds, and fixture log's paired update section. Accepted paired25 stimulus is not blamed; initial simultaneous/unpaired stimulus remains excluded. Fixture log documents user event+part/request, delayed assistant event+part/status before the next request in the valid section; it does not record controller scroll/layout state or tap timestamps.

Material evidence correction (not a QA pass override):

  • paired-live-latest.png shows a partially visible assistant reply above User23 at the TOP, while reply25 is near the BOTTOM. The newest short row is not the controller's viewport-top current row.
  • paired-live-previous.png starts at User20, not User23. Its paired-live-previous-window.xml reports ScrollView bounds[0,239][1008,1978], User20 text[270,325][945,375], User21 text[270,829][945,879], User22 text[270,1333][945,1383], and User23 text[270,1837][945,1887]. User23 is the lowest fully visible user label, not the top/current ID.
  • paired-live-previous-single-repeat.png starts at User22; User25 is near the bottom. With paired short rows and Latest clearing the logical anchor, Previous from the partially visible reply22 at viewport top should target User22, not unconditionally User25. That repeat is consistent with viewport-based navigation, not proof of logical-newest-adjacent navigation.
  • paired-live-rapid-three-previous.png starts at User21; User24 is near the bottom. The natural viewport sequence is reply22 -> User22 -> reply21 -> User21, consistent with that image. The report's latest-reply25 -> User25 -> reply24 -> User24 sequence reads the bottom label instead of the viewport start.

Source contract: message-navigation.ts:21-38 uses pending target/completed anchor when present, otherwise frame containing top=offset+height; manual(0):57-62 used by Latest clears target/anchor and resets offset, does NOT anchor ids[0]; destination():50-54 aligns target cell start to viewport TOP, clamping at0. Existing short-row/viewport regressions already distinguish this from newest-visible-row navigation. Changing Latest to force ids[0] would change the established viewport semantics and is not justified just to match the unvalidated User25-at-top expectation.

UNRESOLVED, still FAIL/not accepted: failure TOP User20 versus repeat TOP User22 is a real captured viewport difference of two paired rows. Approximate XML label spacing is504px per pair, so the failure/repeat difference is about1008px, not proof of a single adjacent-row displacement. Correcting the label interpretation does NOT establish why it happened or rule out stale metrics/callback timing, a different pre-tap state, extra actions, or capture timing. Specific cause remains UNPROVEN; no speculative patch.

Exact missing sequence needed for a scoped regression: immediately-before-failing-tap viewport screenshot/bounds and ordered tap count/timestamps; then corresponding native offset+layout height, controller current/anchor/target/expected IDs, target measured y/height, and issued scroll destination versus received layout/scroll order. Existing XML gives screen bounds/text but not logical contentOffset/cell coordinates/selected target; fixture request log cannot supply them. At minimum, an identical verified pre-tap TOP row and one settled Previous with before/after screenshots plus action order is needed to separate changing input state from differing target calculation. Do not substitute the bottommost user label for current/target, and do not assert User25-at-top from a short latest row occupying less than the viewport.

Next step is SAME QA/manager reconciliation of actual viewport-start expectations and precise action sequence after its existing report turn, using existing tooling only; no engineer duplicate device run, telemetry/custom harness, or readiness polling initiated. A scoped fix/new build is warranted only when that sequence establishes a feature defect. Composerbaseline UNKNOWN/IME208 excluded. Mockshortreply SSE is not incremental-token/liveAI proof; fullUX/CUA remain incomplete/unwaived. No merge/tag/store/tester upload/distribution claim.

@omgoshjosh

Copy link
Copy Markdown
Author

QA correction (2026-10-02): the earlier intermittent Previous failure claim is withdrawn. It compared bottom-most visible user labels instead of the viewport boundary/current transcript item. On the exact a550126 APK (SHA256 7b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666), a fresh settled capture without the reconnect banner showed User22 at the viewport boundary; one Previous action moved it to the immediately preceding assistant transcript item, and Latest appeared afterward. Focused one-action result: PASS; this does not complete the full navigation/UX matrix. Earlier rapid and Next-Previous verdicts are unreconciled, not claimed as pass/fail. Screenshots/XML and corrected matrix: docs/qa/issue-214-build-a550126/reconcile-02-settled.* and reconcile-03-previous.* / PHYSICAL-QA.md. Pre 2026-10-02T03:51:59Z; post 2026-10-02T03:52:13Z. Full UX and mandatory CUA remain incomplete; no merge/release/upload.

@omgoshjosh

Copy link
Copy Markdown
Author

Superseding21:21QA+cleanupresult atsourcea5501268386a8288440ab842fd7f5c5fc3df7ef2/APK7b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666: focusedtwoRapidPreviousTOPsequence andsettledNextPreviousroundtripPASS; priorbottomlabeljumpwithdrawn. IndependentUXFAILkeyboardopencontrolscoverassistanttext; composeroccludedbaselineUNKNOWN/IME208excluded. QAAppendOneNOTsent,append/autoscroll/longreanchor/virtualizationedgesincomplete. Fixturedoesnotsupportlong/incrementalassistant replies;shortcannedSSEnotliveAIproof.352sourcegatesseparate; nooverallnativeacceptance.

Managercompletedverifiedowner-scopedcleanup: fixturePID38984terminated/absent;port13022FREE/finalQAclaimreleased;ONLYreverse13022removed/readbackEMPTYusingfreshdeviceleases;finalbrokerzero/no drift,formerleasealreadyexpirednotreleased.13021deadclaimownershipunprovenleftalone;allunrelatedCI/Yondiprod.eval/IME208untouched. Evidenceupdated locally/preserved,no source/build/modelchange. SAMEQAonly3callevidencecloseout,nofurtherdevicework. No testerupload/merge/tag/store/CUAwaiver; qualityandtester-onlypolicydecisionsremainpending.

@omgoshjosh

Copy link
Copy Markdown
Author

Issue 214: Source-Only Gutter Attribution

Pins and Scope

New verified source / draft PR215 head:
155e0ba6172c87de92fea0e40861187e3b037595.
Tree: 02283e216ab4e2cbc8c66bb9ed6a49a8d1875d6c.
Commit: fix(chat): mirror Android inverted-list navigation gutter (#214).

Evidence inspected belongs ONLY to source
a5501268386a8288440ab842fd7f5c5fc3df7ef2, APK SHA256
7b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666.
That installed APK was not replaced or relabeled. Existing receipt.json / build.log
and all screenshots/XML remain unchanged under docs/qa/issue-214-build-a550126/.
No new APK or native result exists for 155e0ba.

Read the full QA closeout dated October 1 at 21:34 (UTC October 2 04:34:01),
PHYSICAL-QA.md and MANAGER-UPDATE.md. Independent keyboard-open UX FAIL is
distinct from the withdrawn bottom-label navigation failure. Focused rapid-two
and Next/Previous passes do not clear it. Cleanup remains done; QA was not resumed.

Attributable Feature Defect

Upstream comparison is exact commit
646f9cbf7743e08115c8121d98c82f48d088a8f4, not the already-featured 50f747 APK.
Upstream screen line871 has symmetric padding16; line874 onward has one absolute
Latest target with bottom16/right16/44x44. The feature adds Previous/Next and a
three-slot stack (44x3 + 4x2 = 140dp), plus asymmetric logical paddingRight76
at pre-fix screen line947. The controller and custom cell preserve RN's inversion
style; MessageCell spreads props including style (screen lines210-223).

Installed RN0.81.5 source is decisive:
node_modules/react-native/node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.js:2035-2039
uses transform: [{scale: -1}] for Android's vertical inversion, versus
scaleY: -1 on iOS. The entire Android list therefore flips X as well as Y.
CellRenderer adds the matching inversion to each cell (same dependency,
VirtualizedListCellRenderer.js:204-207,220-226), restoring text orientation,
but content-container left/right padding remains physically mirrored. The
control overlay is outside the list and is NOT mirrored.

Thus logical paddingRight76 reserved the PHYSICAL LEFT, not the controls' right.
This is a concrete error in the feature's overlap remediation, not an inference
from the keyboard policy and not a claim that upstream never overlapped text.

Native Geometry Proof

All rectangles below are actual recorded XML device pixels, not dp or rendered
preview coordinates. The width conversion is consistent with recorded360dpi:
99px target /44dp =2.25; 36px right inset /16dp =2.25;
171px physical-left gutter /76dp =2.25. Display/list width is1008px (448dp).

Evidence Rectangle / State
reconcile-10-keyboard-open.xml and reconcile-11-keyboard-draft-navigation.xml List [0,239][1008,1358], width1008px, height1119px
reconcile-10 Assistant bubble [171,1131][972,1358]; text [189,1237][954,1337]
reconcile-10 Previous [873,1007][972,1106]; Next [873,1115][972,1214]; Latest [873,1223][972,1322]
reconcile-10 Latest/text rectangle intersection [873,1237][954,1322], 81x85px; screenshot shows glyph occlusion
reconcile-11 Assistant bubble [171,942][972,1211]; text [189,1048][954,1148]
reconcile-11 Previous/text intersection [873,1048][954,1106],81x58px; Next/text intersection [873,1115][954,1148],81x33px; screenshot confirms overlap
reconcile-11 Composer EditText [189,1476][873,1570], text QA-focus-draft, focused=true; screenshot visibly shows IME over composer
reconcile-12-draft-cleared.xml Same focused EditText bounds, placeholder instead of draft; keyboard-dismissed screenshot separately shows cleared composer

Assistant bubble's physical-left inset171px equals76dp, while physical-right
inset1008-972=36px equals16dp: exact confirmation of the mirrored gutter.
Text right954px extends81px into the rail starting at873px. These intersections
are feature-control/text geometry, independent of composer attribution.

Correction: new screen lines947-953 use Android paddingLeft76/paddingRight16,
and iOS paddingLeft16/paddingRight76. At the same width/density, source geometry
predicts physical-right bubble edge837px, rail left873px:36px=16dp clearance.
Unchanged bubble markdown inset (MessageBubble.tsx:133,156, padding12 and
marginHorizontal-4) predicts text right819px,54px clear of the rail. These are
PREDICTED corrected coordinates, NOT new-head native measurements. Targets,
stack location, controller, composer and keyboard policy are unchanged.

Composer Attribution Remains Unknown

KeyboardAvoidingView behavior="padding" and Android offset0 exist identically
at upstream screen lines594-609 and current lines641-656. Input safe-area padding
exists at upstream line785 and current line860. No upstream-to-feature delta in
MessageBubble.tsx, markdown renderers or AndroidManifest.xml was found.
This proves unchanged policy/source, NOT that this observed occlusion is baseline.
The old feature screenshot50f747 is not a baseline comparison. App XML does not
contain an IME rectangle; keyboard visibility/occlusion is corroborated visually,
not invented as an exact keyboard bound. No IME208/native patch was made.

ONE missing comparison for composer attribution: upstream646f9cb versus corrected
155e0ba on the same Pixel/IME/density/orientation, identical fixed transcript,
viewport boundary, draft/focus and keyboard state, recording app/list/control/text/
composer and IME bounds. Future finite capture set: keyboard closed and open on
each of those two source builds (four matched captures), no navigation oracle
based on bottom labels. This slice did not build/install/run that comparison.

Source Gates and Remaining Boundary

Strengthened the existing source-pattern layout regression to evaluate actual
style for Android/iOS, accounting for physical mirroring. It FAILED on a550126
with android: physical-right text must clear the control rail and gap, then
PASSED after correction. No native rendering is claimed by this test.
After the source change: npm test352/352 passed, zero failures; typecheck,
version parity0.4.15/code42, diff and staged-diff checks passed. Full test output:
/Users/josh/.local/share/opencode/tool-output/tool_0faffa4190017G7dHfZ5qwk0jg.
Only screen style/comment and existing regression were committed/pushed.
Tracked checkout clean; historical evidence dirs preserved. This report is
uncommitted evidence, not included in the source commit.

NEXT boundary requires separately authorized fresh isolated exact-head build
receipt and independent geometry validation. Do not resume QA/device/build here.
Native/UX acceptance remains BLOCKED, mandatory CUAAGENTS185-191 unwaived,
composer attribution UNKNOWN, tester delivery/manual-policy decisions pending.
No merge/tag/store/upload/release or cleanup/resource changes performed.

Fixture-Only Proposal (Not Implemented or Run)

Source inspected: tests/fixtures/mock-opencode-server.ts.

Already available:

  • MockServerOptions lines80-83 and createMockOpencodeServer lines208-216 already
    accept arbitrary replyText and replyDelayMs programmatically (default300ms).
    CLI parseArgs lines663-670 exposes only port/fail-auth/seed flags: lack of a
    long-reply CLI is a configuration coverage gap, not inability of the API itself.
  • POST /session/:id/prompt_async lines610-628 accepts
    {parts:[{type:"text",text:"numbered user body"}]}. User record/parts persist
    before message.updated {info} then message.part.updated {part} SSE
    (lines343-369). No extension is needed for short append-while-browsing or Latest
    append observation via a direct fixture request; app-send remains a separate
    composer-dependent check. Do not claim the unsent QAAppendOne was appended.
  • scheduleReply lines372-403 delays, broadcasts busy, a new assistant info,
    one complete text part, persists completed history, then idle. It has no
    repeated partial updates. GET history lines599-607 returns all stored rows;
    it does not implement paginated-server coverage.

Smallest long-row setup proposal: expose existing replyText through CLI
--reply-text-file <path> in parseArgs, and optionally expose existing
--reply-delay-ms. Use a fixture-data file with70 numbered, wrapping lines plus
unique start/end markers; existing prompt parts provide numbered long user rows.
Create25 sequential pairs, waiting for each reply/idle before next user. That
supplies50 long rows for partially-visible/exact starts, beyond-render-window
virtualization and first/last bounds without a new seeding endpoint/harness.
Then issue ONE numbered append while browsing an older row, verify retained
boundary, use Latest, and issue ONE more append at Latest to evaluate follow.
No fixture code/data/runner was created or run in this slice.

Smallest incremental-mock proposal: add opt-in replyChunkChars and
replyChunkDelayMs to the existing options/scheduleReply, exposed by matching
CLI flags only if needed. Use the same messageID/partID/sessionID for every
message.part.updated {part:{id,sessionID,messageID,type:"text",text:<cumulative prefix>}};
the consumer replaces same-ID parts (src/stores/sessions.ts:437-451), so emitting
isolated deltas as full parts would be wrong. Suggested bounded data:128-char
increments every100ms over the same70-line payload. Persist the growing record
before each broadcast so GET matches live state; busy once, assistant
message.updated once to create it, cumulative part updates, then completed info
via message.updated and idle ONLY after the final prefix. Pending chunk timers
must be owned/canceled on fixture close. No store/backend changes are needed.
Repeated SSE prefixes are incremental MOCK TEXT acceptance only, not token timing,
live model inference or live backend proof. Unsupported cases stay COVERAGE GAPS,
not invented product passes/failures. Fixture implementation requires a later
explicitly scoped boundary; no launch/testing of this proposal occurred here.

@omgoshjosh

Copy link
Copy Markdown
Author

Issue 214: Finite 155e0ba Build Receipt

BUILD SOURCE and independently verified before/after draft PR215 head:
155e0ba6172c87de92fea0e40861187e3b037595.
Tree: 02283e216ab4e2cbc8c66bb9ed6a49a8d1875d6c.
Tracked source clean before/after. Before: preserved untracked419beced/a550126
evidence directories and ISSUE-214-GUTTER-ATTRIBUTION-155e0ba.md. After: only
this additional untracked155e0ba evidence directory. No evidence commit/push.

Absolute evidence directory:
/Users/josh/agents/worktrees/mobile-message-navigation-214/docs/qa/issue-214-build-155e0ba.
Actual lease/Gradle exit 0. UTC start 2026-10-02T05:38:47.585Z;
UTC end 2026-10-02T05:39:17.902Z. BUILD SUCCESSFUL in 27s.
Working directory: worktree android/.

/Users/josh/agents/bin/lease run --owner ses_f0aaeaf99ffedwO7e5cr1OKoyB --project mobile --priority experiment --ttl 1800 android-build -- ./gradlew assembleRelease -PreactNativeArchitectures=arm64-v8a --max-workers=2 --console=plain --no-build-cache --init-script /var/folders/fc/xccpf99d62b5_sc13zpgvjd80000gn/T/opencode/issue-214-419beced.init.gradle

Existing external finalizeDsl override retains its historical filename, NOT a
source pin. Receipt captures full path/content/hash, isolated application ID,
development signing and forced fresh Metro task. Override SHA256:
da7149ff5a3da877b8da76dccfa431b4caafb9e5d4537e67e00cc46f7fafd162.
Build cache disabled. Log1560-1567 shows bundle task executing, Metro2508 modules,
and output written (not UP-TO-DATE/FROM-CACHE).

Environment names only (no secret values) are in receipt; safe overrides:
ANDROID_HOME/ANDROID_SDK_ROOT /Users/josh/Library/Android/sdk, JAVA_HOME
/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home,
SENTRY_DISABLE_AUTO_UPLOAD=true, EXPO_NO_DOTENV=1; release signing variables
omitted, existing ignored development keystore used. No credential/account changes.

File SHA256
receipt.json 7061cc6b2d4d6d62e40a0043e49dc1839d85197b0c03f72132635e803f7972e7
build.log bd69cbf60d509ccdc49545c07b4178863d85dca5a3b80d7b254f9659a2e01a55
navigation214-155e0ba-arm64-release.apk 6981bc2abbbf7a4af3ead5533daa470fd9aa9c69c4a957f5cf3b7a1d8cf2f4dd
index.android.bundle (extracted from APK) 5b161d4d9f91df5ac8073ae22ca044785fceb13c0642b7004af66b1cefe1dea1

Actual manifest: package cc.agentlabs.opencode.navigation214, versionName
0.4.15, versionCode 42, ABI arm64-v8a.
Verified signer certificate SHA256:
0b9c1685876036903653decbd84840474ff09db07fe8958e846443b2ee5c1fae.
Receipt contains exact manifest/signature, before/after source hashes and broker
final status: zero leases, no drift. Disk before build41.2GB free. Postbuild diff
check passed. Existing352 tests/typecheck/version checks not rerun absent changes.

One build only; no engineer device work, source/fixture changes or baseline build.
Historicala550126 APK hash 7b135723f1d091856f50a42c14194cc48d9adc431de7797a0746b07d04555666
and its exact receipt/runtime evidence remain untouched in the old directory;
they are NOT155e0ba native evidence.

No identified owned isolated baseline APK with proven upstream
646f9cbf7743e08115c8121d98c82f48d088a8f4 source/receipt is known. No workspace
artifact scan or second build performed. EXACT missing baseline input: upstream-
provenance isolated APK plus compatible installation/signing/build receipt.
Composer attribution remains UNKNOWN, not baseline-only.

SAME QA single postbuild readiness check returned READY with no children/unread/
owed reports. Provided finite QA prompt will be sent without model/agent args,
with this receipt and actual hashes identified. No new QA/model/context switch.
Native geometry and UX results must come from that finite independent run;
build/source tests do not grant acceptance. CUAAGENTS185-191 remains unwaived,
tester/manual-policy/delivery decisions pending; no merge/tag/store/upload/release.

@omgoshjosh

Copy link
Copy Markdown
Author

155e0ba QA setup-only report: exact draft PR head/tree and build provenance were verified; the pinned arm64 APK was installed once to the isolated navigation214 package. Production/.eval were untouched. The hard 16-tool-call limit required stopping before app launch/UI capture to reserve cleanup. Therefore keyboard-closed gutter, keyboard/composer UX, navigation, appends/Latest, and independent UX are NOT RUN; no native acceptance is claimed. Existing fixture PID 44563 on owned port 13022, its only ADB reverse, port claim issue-214-155e0ba-qa-ses-f06bab859ffeE0daJWiGLS5nSm, and live lease lease_muqje1g2_agpo2t were cleaned up and read back clear; broker zero leases/no drift. Full pin, hashes, limitation, and cleanup receipt: docs/qa/issue-214-build-155e0ba/PHYSICAL-QA.md and MANAGER-UPDATE.md. CUA remains unwaived; no merge/tag/upload/release.

@omgoshjosh

Copy link
Copy Markdown
Author

Exact-head physical UX update for 155e0ba6172c87de92fea0e40861187e3b037595: keyboard-closed controls/bubble separation observed; keyboard-open composer and send row are obscured by the IME (FAIL). Testing stopped at this first blocker, so navigation and append/Latest checks remain unrun; overall UX acceptance is not accepted and mandatory CUA remains unwaived. Details/capture paths are in the Issue #214 update: #214 (comment). Owned fixture/ADB/port/lease cleanup verified.

@omgoshjosh

Copy link
Copy Markdown
Author

Historical Baseline Setup Failure

The October 2, 2026, 00:09 PDT engineer report supersedes the earlier manager statement that a baseline build was in progress. This attempt failed during provenance setup. Gradle invocations: 0. Build leases acquired: 0. No baseline APK was produced. This was not a compiler failure.

Exact Inputs

  • Baseline source: 646f9cbf7743e08115c8121d98c82f48d088a8f4.
  • Baseline tree: b16b19c9efc71e4e41b3fc6afe3a2d53a577649a.
  • Feature source: 155e0ba6172c87de92fea0e40861187e3b037595.
  • Existing feature APK SHA256: 6981bc2abbbf7a4af3ead5533daa470fd9aa9c69c4a957f5cf3b7a1d8cf2f4dd.
  • Failed helper: /var/folders/fc/xccpf99d62b5_sc13zpgvjd80000gn/T/opencode/issue-214-baseline-build.cjs.
  • Failed helper SHA256 recorded before correction: 47b63ceba4ecb16dd81a2f0b3be8ca75a5430f28a654d03ccfd1b3e85d955851.

Failure And Input Identity

The helper's snapshot used readFileSync to hash every git ls-files entry as a regular file. It followed the tracked symlink .claude/skills/app-store-optimization to a directory and threw EISDIR before receipt initialization and build dispatch.

Verified Git entry: mode 120000, blob d69a57b9d57bea0f65116f42616de89827bad636. Both blob content and filesystem symlink target are ../../.agents/skills/app-store-optimization. lstat identifies the entry as a symlink, not a regular file or directory. Its resolved target is a directory. The prior baseline inspection found no mode 160000 entries; this failure must not be described as an established gitlink failure.

Historical Cleanup

The engineer released and safely deleted mobile-214-baseline-646f9cb and local branch experiment/214-baseline-646f9cb. Subsequent manager verification found no baseline checkout in the worktree registry. The feature checkout remained at its pinned head with no tracked changes and preserved untracked evidence. The engineer recorded zero leases and no drift; no QA fixture/device work was started in this attempt.

Renewed Authority, Not Completion

The human subsequently authorized ONLY a helper/preparation correction, one focused regression, one renewed setup, and the first actual isolated baseline build. Both same workers were checked idle before the manager dispatched this scope to the same engineer. QA remains reserved for a validated pair.

The correction must distinguish regular-file content, symlink target identity, directory/tree identity, and gitlink commit/availability/dirty state where applicable. Missing inputs are blockers, not evidence of equivalence. Preserve the failed attempt separately from later results. Stop at the next first failure without automatic retry.

Helper diff/regression results, first actual build outcome, validated baseline APK, and paired keyboard comparison are not yet reported. Existing feature gutter PASS and keyboard-open composer FAIL remain separate; attribution is UNKNOWN. No feature/native/IME208 changes, publication, merge, or CUA waiver are authorized.

@omgoshjosh

Copy link
Copy Markdown
Author

Baseline build for the keyboard comparison: PASS (one attempt). Runtime attribution: still UNKNOWN.

  • Helper gate: the old provenance helper was rerun on the fixed fixture and reproduced EISDIR on a tracked mode-120000 symlink pointing to a directory. This is valid red evidence. The corrected helper then passed (GREEN), with each tracked entry typed as a regular file, symlink target, Git tree or gitlink. The earlier EISDIR setup failure and ReferenceError fixture failure stay on record unchanged.
  • Baseline build: 646f9cbf7743e08115c8121d98c82f48d088a8f4, one assembleRelease under a broker android-build lease, exit 0. APK sha256 af56341994420e71d2acce43080fdb922322cad3ae65b9a42bf3a31728875cb4.
  • Matched to feature: 155e0ba / APK sha256 6981bc2abbbf7a4af3ead5533daa470fd9aa9c69c4a957f5cf3b7a1d8cf2f4dd. Compiled manifest, badging and signer are exactly equal, and native input hashes are equal. Package cc.agentlabs.opencode.navigation214, windowSoftInputMode 0x10, edge-to-edge and new architecture on, arm64-v8a.
  • Cleanup: the temporary baseline worktree was released and deleted, and no leases are held. The feature checkout is unchanged.

Next: one paired keyboard-closed/open device comparison, baseline first, then the feature APK is restored. The earlier 36px gutter PASS and the current composer FAIL remain as recorded. This is not UX acceptance, CUA clearance or tester delivery.

@omgoshjosh

Copy link
Copy Markdown
Author

Paired keyboard comparison: BOTH FAIL. The keyboard covers the composer and send row identically in the upstream baseline and in this PR.

Baseline 646f9cbf Feature 155e0ba6
APK sha256 (installed copy pulled and re-hashed) af563419…875cb4 6981bc2a…cf2f4dd
Composer bounds, keyboard open [189,1476][873,1570] [189,1476][873,1570]
Send button bounds, keyboard open [891,1480][981,1570] [891,1480][981,1570]
IME inset frame [0,1385][1008,2244] visible [0,1385][1008,2244] visible
Composer / send row covered by IME yes yes

Both runs used identical conditions:

  • Device: Pixel 8 Pro, physical, Android 16 build CP1A.260505.005.
  • Keyboard: SwiftKey 9.13.16.5.
  • Display: 1008x2244 at density 360, font scale 1.0, portrait.
  • Soft-input mode: adjust=resize (manifest value 0x10).
  • Same mock transcript, same draft, composer focused.

Baseline was captured first, then the feature APK was reinstalled. I verified afterwards that the feature APK is the one installed (pulled hash 6981bc2a…).

Cleanup:

  • Fixture stopped.
  • adb reverse cleared.
  • Port 13022 is free.
  • Leases: 0, drift none.
  • Temporary baseline worktree released and deleted.

What this means

  • The composer occlusion is existing upstream behavior and was not introduced by feat(chat): navigate previous and next message starts #215.
  • The 36px gutter PASS stands.
  • The earlier 352 source checks are historical only.
  • The following remain incomplete:
    • native append
    • long-stream virtualization
    • independent UX review
    • the policy gates, including the mandatory CUA
  • BOTH FAIL is not UX acceptance, CUA clearance or tester readiness.
  • All historical failure records are preserved: the EISDIR setup failure, the fixture ReferenceError and the corrected oracle.

Next boundary: fixing the shared keyboard/composer issue needs a new, explicit IME/shared-policy scope. IME PR #208 has not been touched. Nothing was fixed, released, merged or uploaded, and CUA was not waived.

Evidence: docs/qa/issue-214-paired-keyboard-646f9cb-vs-155e0ba/ (COMPARISON.md, comparison-receipt.json, MANAGER-CLOSEOUT.md). These are untracked local evidence files, not pushed.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile chat: previous and next message navigation

1 participant