diff --git a/packages/paperclip-runner/docs/design/mockups/phase-7i-mobile-chat.html b/packages/paperclip-runner/docs/design/mockups/phase-7i-mobile-chat.html new file mode 100644 index 00000000000..136a6e6fed3 --- /dev/null +++ b/packages/paperclip-runner/docs/design/mockups/phase-7i-mobile-chat.html @@ -0,0 +1,424 @@ + + + + + +Phase 7I scenario chat — annotated mockup (ix-checkbox-01) + + + +
+

Phase 7 scenario chat — mock control plane

+ 106 scenarios · 16 groups · mock adapter only, no credentials in the browser +
+
+ 1 session header + status + reset/replay + 2 control-plane strip (turn 0 seed) + 3 user turn + 4 model output + 5 semantic tool call (expanded) + 6 denied operation + 7 turn activity strip + 8 composer + 9 per-turn activity group + 10 mobile segments + deny chip +
+ +
+ + +
+ +
+ + +
+
+
+
+ 1 + ix-checkbox-01 +

Subset selection from a known list is a checkbox confirmation

+
+
+ Interactions ix + Always tool + Live · Codex (bounded) + ✓ Parity · 2 turns pass +
+
+ + + + + + + + Controls disabled while turn 3 is running +
+
+ +
+ ⌘ +
+

2 Control plane seeded ix-checkbox-01, routed the scoped wake, and checked out task MCK-102 — no agent tool exists for this.

+

Session start · 4 events · exposure: 8 always · 2 optional · 5 control-plane (no tool)

+
+
+ +
3 Read the task and confirm which files I should delete before you act.
+ +
+

4 I read task MCK-102. It asks for a cleanup of generated fixture files. Before touching anything I need your selection, so I'm raising a checkbox confirmation with the candidate files.

+
+ +
+
+ 5 + request_human_input + Always tool + kind=checkbox · committed +
+
+
+
operation
request_human_input@1
+
claims
(always catalog — none required)
+
idempotency
checkbox:MCK-102:cleanup:rev-3 · first commit
+
redactions
••• redacted secret-hygiene
+
+
{ "kind": "checkbox", "prompt": "Check the files to delete.",
+  "options": [ { "id": "draft-report-march" }, { "id": "tmp-export-2025" } ],
+  "minSelected": 0 }
+
+
+ +
+
+ 6 + decide_approval + Optional tool + ✕ Denied +
+
+ Denied: missing claim approval:decide. + The authorization engine rejected the call before any state was read — no protected + state is included in this record. +
+
+ +
+ ⌘ +
+

Control plane registered the pending interaction and scheduled the continuation wake — interaction continuations are routed by the control plane, not requested again.

+

state change: interactions +1 · wake scheduled (fixture time t+3)

+
+
+ + + +
+

Checking the interaction result before finishing the task

+
+
+ +
+
+
+ 8 + + +
+

Enter sends. Shift and Enter add a line.

+
+ 8 + + + +
+

Enter steers the running turn. Escape moves focus to Stop.

+
+
+
+ + +
+ + + + diff --git a/packages/paperclip-runner/docs/design/phase-7i-mobile-chat-ux.md b/packages/paperclip-runner/docs/design/phase-7i-mobile-chat-ux.md new file mode 100644 index 00000000000..828bb1f87e5 --- /dev/null +++ b/packages/paperclip-runner/docs/design/phase-7i-mobile-chat-ux.md @@ -0,0 +1,352 @@ +# Phase 7I Interaction Map — Mobile Chat with Visible Mock Activity + +Status: **approved UX contract for 7I implementation** (PAP-16914, 2026-08-09). +Owner: UXDesigner. Implementer: 7I implementation (PAP-16916), consuming the +existing 7C mock adapter, 7D semantic catalog, and 7F explorer components. +Companion records: [Phase 7 interaction map](phase-7-scenario-explorer-ux.md) +(the 7F contract — everything not overridden here is inherited verbatim), +[Phase 4b interaction map](phase-4b-interaction-map.md) (chat console +baseline), [Phase 5 component decisions](phase-5-component-decisions.md). +Mockup: [`mockups/phase-7i-mobile-chat.html`](mockups/phase-7i-mobile-chat.html) +(annotated desktop + mobile renders in `knowledge/evidence/phase-07/`, +`phase-7i-*` slugs). + +Phase 7I adds a **Codex-style interactive chat** over the same package-local +Phase 7 runner and mock `ControlPlanePort`. The board opens a scenario, chats +with the agent, and — this is the point of the phase — **sees the mock +Paperclip activity for every turn** instead of having it hidden behind chat. +The 7F explorer remains unchanged as the corpus-review surface; the chat is a +sibling surface in the same app shell, one React tree, sharing the picker, +transcript grammar, inspector components, and token layer. + +The 7F authority rule is binding here too: the chat UI renders records the +runtime produced. It computes no exposure, evaluates no claim, applies no +redaction, holds no credential, and never re-times or reorders the artifact +stream. + +## 0. Naming, vocabulary, and the turn model + +- Surface name in the UI: **Scenario chat** (header: “Phase 7 scenario chat — + mock control plane”). +- All 7F §0 vocabulary carries over exactly: **task** in copy; machine values + (case IDs, `MCK-102`, grants, JSON) verbatim in `--pcr-font-mono`; + disposition labels **Control plane / Always tool / Optional tool**; parity + statuses **Pass / Fail / Intentional gap / Not run** always icon + text. +- A **turn** is one user message and everything the runtime records until the + agent settles (model output, semantic calls/results, authorization + decisions, control-plane actions, state changes, reconciliation events, + and the turn parity verdict). Turns are numbered from 1 in artifact order. +- **Session start** is turn 0: the control-plane-owned seeding record (wake + payload, checkout, initial tool exposure) that exists before any user + input. It renders with full control-plane styling — the demo must show + that work happened with no agent tool before the first message. + +## 1. Shell and information architecture + +Same Vite entry, same app shell as 7F (`examples/phase7-explorer/`), new +routes under `#/chat/…` (§9). No second app, no second token sheet. + +Desktop (≥ 64rem), three regions, one React tree: + +- **Left rail (`--pcr-rail-width`, 17rem):** the existing 7F scenario picker, + reused as-is (search, facets, grouped case list). Selecting a case in chat + context seeds a chat session for that scenario instead of a fake run. +- **Center column (fluid, max `--pcr-center-width`, 48rem):** the **chat** — + session header, conversation, and composer. Primary surface, strongest + hierarchy. The composer is pinned to the bottom of the column. +- **Right rail (26rem, proposed token `--pcr-activity-width`):** the + **Activity stream** — the ordered per-turn evidence (§4). Open by default + on desktop; it carries the acceptance evidence, so it is never a + collapsed-by-default drawer on desktop. + +Mobile (< 64rem): single column behind the established segmented control +pattern (a `radiogroup`, per 7F revision 4), with exactly two segments: +**Chat · Activity**. The segmented control is sticky at the top; the +composer is sticky at the bottom of the Chat segment (thumb zone). The +Activity segment contains the complete §4 stream as stacked cards — mobile +gets **all** the evidence, never a summary-only view. A count chip on the +Activity segment surfaces attention states without opening it +(“Activity · 1 deny”). + +Density: diagnostic-console dense. All values from `--pcr-*` tokens only +(`DESIGN.md` principles 2–4); the two 7F token-layer overrides (badge +min-width / text-transform, 7F revision 5) apply to the chat surface too. + +## 2. Session header, scenario selection, reset and replay + +The session header replaces the 7F run header on chat routes: + +- **Row 1:** case ID (mono) + title, group badge, disposition badge. +- **Row 2 — session status chip**, exactly one of: + - **Live · Codex (bounded)** (accent surface) — a real model is connected + through the server-side relay; + - **Replay · deterministic** (muted surface) — the scripted session is + playing or played; + - **Idle** (muted) — seeded, no turns yet. +- **Row 3 — controls:** mode segmented control (`Replay (scripted)` default / + `Codex (bounded)` when the relay is reachable — same availability and + disabled-reason rules as 7F §3.1), **Reset session**, and **Replay** + (re-runs the recorded session deterministically). Reset is a destructive + affordance: it clears the session back to the seeded turn-0 state and asks + for confirmation via the SDK `Dialog` (“Reset this session? The transcript + and mock state return to the seeded scenario.” — Forgiveness). Replay + needs no confirmation; it reproduces the identical timeline (7F + determinism contract). +- **Parity-so-far chip:** “Parity · 2 turns pass” (success) or + “Parity · turn 2 fail” (danger), deep-linking the newest parity entry in + the Activity stream. + +Scenario switching mid-session prompts the same reset confirmation (the mock +core is seeded per scenario; two scenarios never share mutable state). + +## 3. Chat transcript + +The conversation composes the frozen SDK chat kit: `conversation`, +`message`, `tool-item`, `reasoning-item`, `Composer`. Three actors render +with three distinct visual grammars (Similarity + Common Region — a stranger +must attribute any row to its actor in two seconds): + +1. **User turns** — right-aligned message bubbles on `--pcr-accent-surface`. +2. **Model output** — left-aligned message cards on `--pcr-card` with the + standard streaming affordances (token reveal, jump-to-latest, auto-follow + inherited verbatim from Phase 4b §1; reduced-motion renders instantly). + Reasoning summaries, when the driver emits them, use `reasoning-item` + behind its existing disclosure. +3. **Agent tool work** — semantic calls render inline in the conversation as + collapsed `tool-item` cards on `--pcr-surface-raised`: operation ID + (mono) + disposition badge + one-phrase outcome. Expansion shows the 7D + descriptor fields exactly as in 7F §3.2 (arguments, result, claims, + idempotency, redaction chips). Denied calls render in place on + `--pcr-danger-surface` with the typed denial (operation, missing claim, + reason) — never toast-only, never any protected state. +4. **Control-plane work** — full-width strips on `--pcr-muted` with the + “Control plane” badge and the 7F gutter glyph, copy naming the actor + plainly (“Control plane registered the interaction and scheduled the + continuation wake — no agent tool exists for this.”). Turn 0 seeding uses + this grammar. + +**Turn activity strip (new, binding):** after each completed turn the +conversation appends a full-width summary strip for that turn: +`Turn 2 activity · 3 tools · 1 denied · 2 control plane · diff 2 domains · +parity ✓`, rendered as a single button. Counts are icon + text, never color +alone. Activation opens that turn’s group in the Activity stream (desktop: +scroll + flash the group, same connect cue as 7F authorization rows; +mobile: switch to the Activity segment anchored at the group, with a +“Back to chat” affordance that restores scroll position). The strip is the +guaranteed per-turn bridge — evidence is reachable from the turn itself, +not only by scanning the rail (Recognition over Recall). + +The composer is the SDK `Composer` with its existing state machine — +`idle / submitting / active-turn (Steer) / interrupting / disconnected / +terminal` — and keyboard contract (Enter sends, Shift+Enter newline, Escape +moves focus to Stop during a turn). In Replay mode the composer renders +`disconnected`-style with the reason “Scripted replay — switch to Codex +(bounded) to chat live” and the Replay control adjacent; free-text input is +a live-driver capability, not a replay capability. + +## 4. Activity stream (per-turn evidence) + +**Source of truth:** the ordered run artifact timeline plus per-turn +records (§10 data contract). The stream is grouped by turn; groups render +newest-last and auto-follow the conversation. Each **turn group** is a +collapsible section headed by `Turn N` + the same counts as the turn strip; +the newest turn group is expanded by default, earlier groups collapse to +their header (progressive disclosure; Miller — never all turns fully open). +Inside a group, ordered sections, each rendered only when non-empty, always +in this order: + +1. **Exposed tools** — the turn’s exposure record: Always (N) / Optional (N, + each with its unlocking grant) / Control plane — no tool (N), reusing the + 7F `ExposureList`. Collapsed to counts by default; the acceptance-critical + full list is one disclosure away. +2. **Calls and results** — one row per semantic call: operation (mono), + disposition badge, outcome; expansion identical to the inline tool card. + Rows and their inline conversation twins highlight each other on + selection (uniform connectedness). +3. **Authorization** — the turn’s slice of the 7F `AuthorizationTable`: + decision (Allow/Deny, icon + text), claims considered, reason, + redactions; denied rows on `--pcr-danger-surface`. +4. **Control plane** — the turn’s control-plane actions with their decision + records (inputs considered, resulting state change, audit reference). +5. **State diff** — the 7F `StateDiff` scoped to the turn: per-domain change + summaries, unchanged domains as one muted row, `field: before → after` + in mono. Wake/reconciliation events (continuation scheduling, blocker + resolution, terminal reconciliation) render here as rows in their + domains, badged “Control plane”. +6. **Parity** — the turn verdict row (icon + text + assertion counts), + expanding to the 7F `ParityPanel` assertion rows for that turn. The + session-level verdict lives in the session footer group. + +The stream ends with a **Session** group: cumulative diff against the seed, +session parity verdict, and the restraint note when the correct behavior was +absence (“No further operations — N forbidden operations, none invoked”, +7F §3.2 rule carried over). + +A filter chip row at the top of the stream (`All · Tools · Authorization · +Control plane · Diffs · Parity`) narrows sections across all turns; +filtering never deletes groups, it collapses non-matching sections (the +turn skeleton stays scannable). Filter state is view state, mirrored to the +route (§9), never protocol state. + +## 5. Actor distinction (binding summary) + +| Actor | Surface | Marker | +| --- | --- | --- | +| User | `--pcr-accent-surface` bubble, right-aligned | — | +| Model output | `--pcr-card` message card, left-aligned | streaming caret | +| Agent tool work | `--pcr-surface-raised` collapsed card, conversation-indented | mono operation + disposition badge | +| Control plane | `--pcr-muted` full-width strip | “Control plane” badge + gutter glyph | +| Denied (any) | `--pcr-danger-surface` in place | Deny icon + text | + +No view — chat, activity, expanded detail — may render a fact without its +actor attribution. If a record ever lacks attribution, that is a 7C artifact +defect to fix upstream, not a UI guess. + +## 6. Credentials, redaction, denial + +7F §5 applies verbatim (including revision 11: redaction chips render +`••• redacted ` inline, no tooltip-only disclosure). Additionally for +chat: the composer submits user text to the package-local runner only; in +Codex mode the provider credential stays server-side behind the same relay +boundary proven in Phase 5, and no user-typed text is ever written to +`localStorage` (a page reload may drop an unsent draft; that is the accepted +trade against persisting conversation content). + +## 7. States that must be designed, not defaulted + +| State | Surface | Rendering | +| --- | --- | --- | +| No scenario selected | Chat + activity | Intro card (corpus stats + “Pick a scenario to start chatting” + three example deep links); activity rail shows the 7F corpus summary. No dead panels. | +| Seeded, no turns | Chat | Turn-0 control-plane strips render immediately (checkout, exposure); composer focused and ready in Codex mode; primed hint in Replay mode (“Replay the scripted session, or switch to Codex (bounded)”). | +| Turn streaming | All | Model card streams; composer in `active-turn` (Steer + Stop); the pending turn’s activity group shows a live-updating header (“Turn 3 · running”); controls that would corrupt the run (Reset, Replay, mode switch, scenario switch) disable with reasons. | +| Turn failed (harness/driver error) | Chat | Danger strip in place with the exact diagnostic and a “Retry turn” affordance; the partial activity group stays visible and is labeled partial. Never silently reset. | +| Denied operation | Chat + activity | §3/§4 danger rendering; the Activity segment chip counts denials. | +| Relay unavailable | Session header + composer | Codex option disabled with reason; Replay mode fully usable; composer disabled-reason names the relay, not a generic error. | +| Session terminal | Composer | `terminal` state with its existing hint (“This session is closed. Replay it or reset the session state.”). | +| Reset confirm | Dialog | §2; focus returns to the composer after either outcome. | +| Long JSON / long code / long unbroken strings | Everywhere | `overflow-wrap: anywhere` on prose and key-value values; `pre` blocks may scroll **internally** (x) with a visible affordance, but the page never scrolls horizontally at any viewport ≥ 320px — the 7F `min-w-0` discipline is a hard gate at 390×844. | +| Unknown case ID in route | Chat | The 7F named error card (“No scenario named …”) — not a silent home fallback (closes 7F revision 10’s accepted gap for chat routes). | + +## 8. Touch, keyboard, focus, accessibility + +- Touch targets ≥ `--pcr-touch-target` (2.75rem) for segments, turn strips, + group headers, filter chips, composer buttons. +- Landmarks: `nav` (picker), `main` (chat), `complementary` (activity); + one `h1`; `F6` / `Control+Period` region cycling and the skip link carry + over from 7F (revision 13) with the activity rail as the third region. +- Composer keyboard contract per §3; the turn strip and group headers are + real `button`s; the mobile segment switch preserves and restores scroll + position per segment. +- Focus order on a completed turn: model card → inline tool cards → turn + strip → composer. After “Back to chat”, focus returns to the originating + turn strip. +- Live regions: turn settle announces politely (“Turn 2 settled — 1 denied + operation, parity pass”); a denial announces assertively once, when it + lands (upgrading 7F revision 10’s interim). +- Streaming, flash cues, and auto-follow honor `prefers-reduced-motion` + (instant/static variants, Phase 5 rule). Contrast from existing token + pairs; every status icon + text. + +## 9. Routes and determinism + +Hash routing, extending the 7F scheme: + +``` +#/chat chat home (picker + intro) +#/chat/ live session, seeded (turn 0) +#/chat/?replay=fake deterministic scripted session, auto-played +#/chat/?replay=fake&view=&turn= +#/chat/?replay=fake&filter= +``` + +- `replay=fake` auto-plays the scripted session to completion; when the + conversation and all activity groups are settled the shell sets + `data-chat-state="settled"` (Playwright wait target; `pending` until then). + Fixture time only, no wall-clock values, pixel-identical across loads at + the same viewport — the 7F determinism contract applies unchanged. +- `view=activity` selects the Activity segment on mobile and scrolls the + rail on desktop; `turn=` anchors that turn’s group and expands it. +- Live chat routes (`#/chat/` without `replay`) are the primary + board experience and are exempt from pixel determinism; QA acceptance of + live behavior uses the scripted routes plus one real Codex turn. +- Stable `data-testid`s (minimum new set): `chat-shell`, `session-header`, + `session-status`, `chat-conversation`, `chat-turn-`, + `turn-activity-strip-`, `activity-stream`, `activity-turn-`, + `activity-section--`, `activity-filter-`, `composer`, + `reset-session`, `replay-session`, `segment-chat`, `segment-activity`. + 7F testids keep their meanings. + +## 10. Package-local implementation guidance (7I) + +- **Reuse first.** The chat column composes the SDK chat kit + (`conversation`, `message`, `tool-item`, `reasoning-item`, `Composer`, + `Dialog`, `Badge`, `Banner`) — `RunnerConsoleApp` itself is *not* the + shell (same 7F ruling: compose parts, don’t adopt the console’s + session-timeline IA). The activity stream composes the existing explorer + components: `ExposureList`, `AuthorizationTable`, `StateDiff`, + `ParityPanel`, `ChannelEntry`, `RedactionChip`. +- **New explorer-local components** (one job each): `SessionHeader`, + `TurnStrip` (the per-turn summary button), `ActivityStream` (turn + grouping + filter chips), `ActivityTurnGroup`. Tokens only; the two + candidate new tokens (`--pcr-activity-width: 26rem`, + `--pcr-touch-target` if not yet minted) are proposed as token additions + in the 7I PR, never inlined. +- **Data contract extension (owned by the runtime, not the UI):** timeline + entries gain a `turn` number (0 = session seed); the artifact gains + `turns[]` with per-turn `exposure`, `authorizationRecords`, `diff`, + `reconciliationEvents`, and `parity`, each shaped exactly like their + session-level 7F counterparts. A `user_message` timeline kind joins the + existing five kinds. The session-level records remain and feed the + Session group. The UI must not derive turn boundaries, per-turn diffs, or + per-turn verdicts itself — if the runtime can’t supply a per-turn record, + extend the runtime. +- **Driver seam:** Replay mode consumes recorded fixtures; Codex mode uses + the bounded driver through the Phase 5 relay. The chat UI is + driver-agnostic — it renders whatever the artifact stream says happened. +- **Testing hooks 7I must ship:** component tests for `TurnStrip`, + `ActivityStream` grouping/filtering, and per-turn diff/parity rendering; + keyboard tests (composer contract, strip→group→back-to-chat focus + round-trip, region cycling with the new rail); the §9 route determinism + test; a 390×844 no-horizontal-scroll assertion on a long-JSON fixture; + reduced-motion test; screenshot capture script for §11. + +## 11. Screenshot acceptance matrix + +Evidence lands in `knowledge/evidence/phase-07/` as +`phase-7i--.png` at **1440×900** and **390×844**, captured +from §9 routes after `data-chat-state="settled"`. Mobile captures must show +the correct active segment and no horizontal scrollbar. + +| # | Slug | Route | Expected visible evidence | +| --- | --- | --- | --- | +| 1 | `chat-home` | `#/chat` | Picker + chat intro; no dead panels. | +| 2 | `chat-session` | `#/chat/ix-checkbox-01?replay=fake` | Turn-0 control-plane strips; user/model/tool/control-plane grammars all distinguishable; turn activity strips with counts; composer in its mode-correct state; desktop shows the activity rail with the newest turn expanded. | +| 3 | `chat-denied` | `#/chat/ap-mcp-gate-01?replay=fake&view=activity&turn=1` | Denied call on danger surface in both conversation and authorization section; missing claim + reason; Activity segment chip counting the deny (mobile). | +| 4 | `chat-activity-diff` | `#/chat/ix-checkbox-01?replay=fake&view=activity&turn=2` | Turn group with exposure counts, calls, authorization, control-plane rows, per-turn state diff (changed vs unchanged domains), reconciliation/wake row, turn parity verdict. | +| 5 | `chat-streaming` | live route, staged | Streaming model card, composer `active-turn` (Steer/Stop), pending activity group header, disabled session controls with reasons. Exempt from pixel determinism; capture once per viewport. | + +The scripted fixtures for `ix-checkbox-01` and `ap-mcp-gate-01` chat +sessions are new 7I fixtures (the 7F fake-agent plans are single-shot, not +conversational); they must script at least two user turns each so turn +grouping is actually exercised. + +Acceptance procedure: UXDesigner reviews all ten images against this matrix +before 7I implementation is accepted; deviations are fixed or recorded as +revisions in this document — silent divergence fails the gate (7F §9 rule). + +## 12. Out of scope / rejected + +- All 7F §10 rejections stand (no Tailwind/Radix, no dark mode, no markdown + renderer, no virtualization, no parity re-judging, no live-Paperclip + affordances). +- **No bottom-sheet drawer on mobile.** The segmented Chat · Activity + pattern is proven, keeps one React tree, and route-mirrors; a drawer adds + a new component and an un-linkable state for no evidence gain. Rejected + after comparison, not by omission. +- **No hiding of activity behind a “developer mode”.** Visible mock + activity is the phase’s purpose; there is no toggle that suppresses the + activity stream or turn strips. +- **No per-message edit/regenerate affordances.** The mock core’s + determinism story is session-scoped (reset/replay), not message-scoped. +- Multi-session tabs, session persistence across reloads, and export are + out of scope for the demo. diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-activity-mobile-390x844.png b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-activity-mobile-390x844.png new file mode 100644 index 00000000000..27a538795f8 Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-activity-mobile-390x844.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-desktop-1440x900.png b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-desktop-1440x900.png new file mode 100644 index 00000000000..fc0edf8cd74 Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-desktop-1440x900.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-mobile-390x844.png b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-mobile-390x844.png new file mode 100644 index 00000000000..f372f3b3c02 Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-mobile-390x844.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-streaming-desktop-1440x900.png b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-streaming-desktop-1440x900.png new file mode 100644 index 00000000000..4b72826e5d0 Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-streaming-desktop-1440x900.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-streaming-mobile-390x844.png b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-streaming-mobile-390x844.png new file mode 100644 index 00000000000..a26be00596d Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/phase-7i-chat-streaming-mobile-390x844.png differ