Skip to content

Commit e8c7f8f

Browse files
authored
Merge pull request #67 from dasomji/agent/android-question-chat-planning-evidence
docs: publish Android Question Chat planning evidence
2 parents 07e2c10 + 566b6a3 commit e8c7f8f

12 files changed

Lines changed: 658 additions & 0 deletions
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Accepted native Android Question–Chat workspace
2+
3+
**Planning ticket:** [Prototype the native Question–Chat workspace](https://github.com/dasomji/pi-postbox/issues/61)
4+
5+
**Human decision:** **A — Workspace tabs**, accepted through Pi Postbox on 2026-07-29.
6+
7+
## Prototype question
8+
9+
Which native Compose information architecture keeps a pending Postbox Question and its temporary Question Chat clear through activation, fallback, streaming, recovery, and return-to-answer on a narrow Android screen?
10+
11+
A throwaway interactive browser prototype compared three structurally different mobile models:
12+
13+
1. **Workspace tabs:** the Postbox Question remains primary before activation; afterward, Question and Question Chat become peer tabs.
14+
2. **Question Chat sheet:** Question Chat lives in a near-full-height modal sheet over the Postbox Question.
15+
3. **Decision companion:** Question Chat becomes primary beneath a persistent compact decision rail, with the Postbox Question reopened in a review sheet.
16+
17+
The human selected **Workspace tabs**. It has the clearest native navigation and accessibility model, keeps the authoritative answer surface distinct from guidance, avoids modal-sheet/IME/nested-scroll complexity, and makes the return from a Chat-suggested option explicit.
18+
19+
## Accepted interaction model
20+
21+
### Before activation
22+
23+
- Show no workspace tabs. The existing Postbox Question remains the full primary surface.
24+
- Place a secondary **Start Question Chat** action after the question context and before answer options. Its supporting copy says Question Chat is temporary and first attempts an exact fork.
25+
- Starting Question Chat never changes or submits a draft answer.
26+
27+
![Pre-activation Question Chat entry](assets/android-question-chat-workspace/entry.webp)
28+
29+
### Exact-fork failure and context-only fallback
30+
31+
- Keep the user on the Postbox Question.
32+
- Show the server-provided exact-fork failure as an inline warning with one **Consider context-only interviewer** action.
33+
- That action opens a native confirmation surface with the full distinction: a context-only interviewer starts fresh from persisted handoff context and is not an exact fork of the originating Pi Session.
34+
- Confirmation is explicit and cancellable. Cancel leaves the Question unchanged.
35+
- After confirmation succeeds, reveal the tabs, select **Question Chat**, and keep a persistent degraded/context-only disclosure in that tab.
36+
- If the server says context fallback is unavailable, show the reason and Retry/return path without offering confirmation.
37+
38+
![Explicit context-only interviewer confirmation](assets/android-question-chat-workspace/context-only-confirmation.webp)
39+
40+
### Activated workspace
41+
42+
- Add a two-item native tab row directly below the existing app bar: **Question** and **Question Chat**.
43+
- Each tab owns one full-width, independently scrollable panel. Do not use a narrow split pane in this implementation slice.
44+
- Preserve the Question draft selection and note while moving between tabs.
45+
- Preserve Question Chat scroll/state through ordinary in-memory owner state; do not persist its transcript or draft.
46+
- When Question Chat is selected, Android Back first returns to **Question**. Normal app navigation/back behavior resumes from the Question tab.
47+
- Tab state is keyed with the current server and request ID and resets when either changes.
48+
49+
### Empty Question Chat
50+
51+
- Show a concise explanation that Question Chat can help understanding but cannot answer the Postbox Question.
52+
- Present the three deterministic starters: **Elaborate**, **Pro–Cons**, and **Teach me**.
53+
- Keep the freeform composer visible at the bottom.
54+
- Label the exact-fork/context-only mode and model without making model metadata the primary hierarchy.
55+
56+
### Streaming, steer, tools, and Stop
57+
58+
- Stream assistant content into a message list above an anchored composer.
59+
- During generation, keep the composer enabled and relabel its action **Steer**. Supporting text explains that a new message steers the active Question Chat turn.
60+
- Put **Stop** beside the coarse active-turn status, not inside assistant prose.
61+
- Show bounded tool activity as a separate collapsed row/card. It is not assistant Markdown and must not dominate the transcript.
62+
- Announce only coarse state transitions such as Answering, Stopped, Interrupted, Offline, and Ready; the changing assistant body is not a live region.
63+
64+
![Streaming response with Steer, bounded tool activity, and Stop](assets/android-question-chat-workspace/streaming-steer-stop.webp)
65+
66+
### Stopped or interrupted output
67+
68+
- Retain the bounded readable assistant prefix.
69+
- Mark the message itself **Stopped** or **Interrupted** and also expose the coarse workspace state.
70+
- Keep the composer available for a later Question Chat turn when the authoritative state permits it.
71+
72+
![Stopped partial response retained and marked](assets/android-question-chat-workspace/stopped-partial.webp)
73+
74+
### Offline and recovery
75+
76+
- Keep the last authoritative synchronized transcript visible.
77+
- Show one inline **Question Chat offline** or resynchronizing banner with **Retry**.
78+
- Disable composer, Steer, and Stop until the owner is synchronized and online.
79+
- Do not describe in-memory content as “saved”; use “last synchronized messages.”
80+
81+
![Offline disclosure and retry](assets/android-question-chat-workspace/offline-retry.webp)
82+
83+
### Chat-suggested option return
84+
85+
- Render a server-authoritative proposal as a separate **Suggested in Chat** card with **Review in Question**.
86+
- The action selects the **Question** tab and exposes/highlights the authoritative option there.
87+
- It never submits automatically. Existing single/multi validation and the normal answer action remain authoritative.
88+
- Announce that the suggestion is ready for review and not submitted.
89+
90+
| Suggested in Question Chat | Returned to authoritative Question |
91+
|---|---|
92+
| ![Suggestion action in Question Chat](assets/android-question-chat-workspace/suggestion-in-chat.webp) | ![Suggested option highlighted on Question](assets/android-question-chat-workspace/suggested-option-return.webp) |
93+
94+
## Narrow screens and IME
95+
96+
- Use the same tab information architecture at 360 dp and larger; do not introduce a second navigation model by width.
97+
- Give the message list the remaining bounded height and keep the composer above system bars/IME using Compose insets.
98+
- Focusing the composer must bring it into view without replacing tab selection or losing message scroll identity.
99+
- Starters wrap rather than clip. Status/action rows may wrap at narrow widths.
100+
- A visible IME must not cover Send/Steer/Stop or create two competing vertical scroll containers.
101+
102+
![Narrow workspace with visible IME](assets/android-question-chat-workspace/narrow-ime.webp)
103+
104+
## Compose contract for later planning
105+
106+
The prototype settles information architecture, not production component code. The rendering/state tickets should preserve these seams:
107+
108+
```text
109+
Question detail (pre-activation)
110+
-> exact activation attempt
111+
-> inline availability failure + explicit fallback confirmation
112+
-> activated Question | Question Chat tab workspace
113+
114+
Question Chat suggestion
115+
-> authoritative question/proposal update
116+
-> select Question tab
117+
-> highlight valid option
118+
-> ordinary answer submission only
119+
```
120+
121+
Recommended native component shape:
122+
123+
- existing app bar and postal theme;
124+
- Material 3 primary tab row with selected semantics;
125+
- independently keyed `LazyColumn`/Question panel beneath it;
126+
- anchored multiline composer with IME/navigation-bar insets;
127+
- native confirmation dialog or modal bottom confirmation surface for context-only consent;
128+
- Snackbar/status semantics for send-versus-steer acknowledgement and proposal return;
129+
- minimum 48 dp actions and meaningful tab, state, Stop, Retry, and proposal labels.
130+
131+
The dedicated Question Chat owner selected by issues 59–60 remains responsible for server/request identity, lifecycle, bounded snapshots/events, safe Markdown documents, and strict in-memory privacy. Compose receives finite presentation state and emits user intents; it does not own transport or transcript persistence.
132+
133+
## Accessibility acceptance points
134+
135+
- Tabs expose selected state and distinct Question/Question Chat labels.
136+
- Focus enters the confirmation surface and returns to its invoking action when cancelled.
137+
- Switching tabs does not reset the Question draft or steal focus into progressively changing assistant text.
138+
- Coarse status changes are announced once; streamed body replacements are not live-region announcements.
139+
- Tool rows, safe links, Stop, Retry, starters, composer, and proposed-option return have explicit labels and native touch targets.
140+
- The selected Chat-suggested option exposes both selected state and provenance without relying on color.
141+
142+
## Prototype disposition
143+
144+
The interactive three-variant implementation was intentionally throwaway and made no network requests or persistent writes. The selected behavior, rationale, and visual evidence are retained here; losing variant code should be removed rather than promoted to production.
33.6 KB
Loading
35.3 KB
Loading
24 KB
Loading
22.9 KB
Loading
24 KB
Loading
32.6 KB
Loading
32.4 KB
Loading
28.6 KB
Loading

0 commit comments

Comments
 (0)