diff --git a/packages/paperclip-runner/docs/design/mockups/phase-7-scenario-explorer.html b/packages/paperclip-runner/docs/design/mockups/phase-7-scenario-explorer.html new file mode 100644 index 00000000000..63705c0cd45 --- /dev/null +++ b/packages/paperclip-runner/docs/design/mockups/phase-7-scenario-explorer.html @@ -0,0 +1,329 @@ + + + + + +Phase 7 scenario explorer — annotated mockup (ap-mcp-gate-01) + + + +
+

Phase 7 scenario explorer

+ mock control plane · no Paperclip services · no credentials + 106 cases · 16 groups · fake agent +
+ +
+ +
+ +
+ 1 · picker: search + 6 facets + grouped case list + 2 · run view: verdict banner + mode + transcript + 3 · inspector: Context · Authorization · Diff · Parity + + + +
+
+
+

ap-mcp-gate-01

+ ap + Optional tool + Authorization + Multi-hop +
+
Pending MCP tool approval means review posture — no retry, no done.
+ +
+
+ + Codex disabled: provider relay not running — see tutorial §4 +
+
+ +
+ 4 · control-plane channel: muted, “no tool exists” +
+ ⛭ +
+

Control plane routed scoped wake and checked out task MCK-102.

+

No agent tool exists for checkout — control-plane owned. Decision record

+
+
+ +
+

Agent — I need the workspace runtime status before restarting the flaky service.

+
+ +
+ + get_task_context + Always tool + Allow + committed · 41ms fixture-time + +
+
+
Operation
get_task_context · v1
+
Claims
(task-scoped, none required)
+
Idempotency
read-only
+
+
{ "task": "MCK-102", "wake": "scoped", "ancestors": 2, "documents": 1 }
+
+
+ +
+ 5 · typed denial: missing claim, no protected state +
+ control_workspace_service + Optional tool + Deny + policy denial — approval gate pending +
+
+ Denied: requires claim workspace:control — MCP approval + apr-0117 is pending. Typed denial only; no workspace state returned. +
+
+ +
+

Agent — Approval is pending, so I will not retry. Parking the task for review with a durable explanation.

+
+ +
+ + request_review + Always tool + Allow + committed · task → in_review + +
+
+
Operation
request_review · v1
+
Redactions
••• api-key in explanation draft, rule secret-value
+
+
{ "disposition": "in_review", "reason": "mcp_approval_pending", "approval": "apr-0117" }
+
+
+ +
No further operations — 3 forbidden operations, none invoked · Parity
+
+
+ + +
+ + diff --git a/packages/paperclip-runner/docs/design/phase-7-scenario-explorer-ux.md b/packages/paperclip-runner/docs/design/phase-7-scenario-explorer-ux.md new file mode 100644 index 00000000000..30217067249 --- /dev/null +++ b/packages/paperclip-runner/docs/design/phase-7-scenario-explorer-ux.md @@ -0,0 +1,433 @@ +# Phase 7 Interaction Map — Scenario Explorer and Screenshot Acceptance Spec + +Status: **approved UX contract for 7F implementation** (PAP-16899, 2026-08-09). +Owner: UXDesigner. Implementer: 7F (browser scenario explorer), integrating +7C mock adapter output and 7E parity output. +Companion records: [Phase 7A capability contract](../phase-07-capability-contract.md), +`spec/phase-07/eval-traceability.yaml`, [Phase 7 plan](/PAP/issues/PAP-16897#document-plan), +[Phase 4b interaction map](phase-4b-interaction-map.md), +[Phase 5 component decisions](phase-5-component-decisions.md). +Mockup: [`mockups/phase-7-scenario-explorer.html`](mockups/phase-7-scenario-explorer.html) +(annotated desktop + mobile renders in `knowledge/evidence/phase-07/`). + +This map is the interaction contract for the Phase 7 browser scenario +explorer. The explorer is a **read surface over records the runtime already +produced**. It renders scenario metadata from the generated 7A traceability +manifest, run artifacts from the 7C mock control-plane adapter, and parity +results from the 7E conformance suite. The UI never owns state, policy, +credentials, or execution decisions: it does not compute tool exposure, does +not evaluate claims, does not apply redaction, and holds no Paperclip or +provider credential. Every allow/deny, redaction, and state transition shown +on screen must arrive as a record emitted by the mock core. + +## 0. Naming, vocabulary, and canonical labels + +- Product name in the UI: **Scenario Explorer** (header: “Phase 7 scenario + explorer — mock control plane”). +- UI copy uses the canonical term **task** (`DESIGN.md` principle 7). Eval + case IDs, fixture IDs, route paths, JSON payloads, and source anchors are + machine values and stay verbatim (`issues`, `i-0102`, `MCK-102`) in + monospace — never “translated.” +- The three dispositions render with exactly these labels, everywhere: + **Control plane** (`control_plane_owned`), **Always tool** + (`always_agent_tool`), **Optional tool** (`optional_agent_tool`). The + traceability panel and all badges must use the 7A contract values as their + source; no UI-local re-classification. +- The five assertion classes render as: **Invariant** + (`control_plane_invariant`), **Tool contract** (`agent_tool_contract`), + **Authorization** (`authorization_policy`), **Multi-hop** + (`combined_multi_hop`), **Restraint** (`restraint_no_call`). +- Parity statuses: **Pass**, **Fail**, **Intentional gap**, **Not run**. + Each has an icon + text label; color alone never encodes status (WCAG + color-independence). + +## 1. Shell and information architecture + +Package-local Vite entry `examples/phase7-explorer/` with script +`demo:phase7` (default port 4183; 4182 belongs to the Phase 6 demo). It runs +from static assets plus checked-in fixtures with **no Paperclip services and +no network dependency** in fake-agent mode. Reuse the frozen `0.1.2` SDK +surface (`@paperclipai/paperclip-runner/react` + `./styles.css`) through its +five approved extension points; do not fork the token layer. + +Desktop layout (≥ 64rem), one React tree (Phase 5 finding — never render two +trees): + +- **Left rail (`--pcr-rail-width`, 17rem):** scenario picker — search, + facet filters, case list grouped by eval group. +- **Center column (fluid, max `--pcr-center-width`, 48rem):** run view — + the chronological scenario transcript and the run header (verdict banner, + mode toggle, run/replay controls). Primary surface, strongest hierarchy. +- **Right rail (`--pcr-inspector-width`, 24rem):** inspector with four tabs + — **Context · Authorization · State diff · Parity**. Open by default on + desktop (unlike the 4b protocol inspector: here the inspector carries + first-class acceptance evidence, not diagnostics). + +Mobile (< 64rem): single column behind a segmented control +(`Scenarios · Run · Inspect`), same pattern as the Phase 4b console. The +segmented control is sticky at the top; the Run segment is the default when +a case is selected via route. Touch targets ≥ `--pcr-touch-target` (2.75rem). + +Density: diagnostic-console dense, like 4b. All spacing, color, type, radius, +motion from `--pcr-*` tokens only (`DESIGN.md` principles 2–4; `pnpm +check:token-gates` applies). + +## 2. Scenario picker and filters (left rail) + +**Source of truth:** the generated scenario index derived from +`spec/phase-07/eval-traceability.yaml` (all 106 cases, 16 groups) plus the +latest parity results artifact from 7E. The picker consumes these; it never +re-derives group membership or dispositions. + +Contents, top to bottom: + +1. **Search input** — substring match on case ID and title. Mono rendering + of matched IDs. Debounce ≤ 150ms (Doherty). +2. **Facet filters** (collapsible group, `--pcr-facet-height` baseline): + - **Group** — the 16 eval groups (`hb 5 · co 6 · st 8 · cm 6 · se 4 · + su 4 · bl 5 · dp 3 · ix 9 · ap 6 · ar 4 · er 9 · rf 22 · mh 4 · rs 3 · + wk 8`), each with its case count. + - **Case** — direct case-ID picker (combobox) for jump-to-case. + - **Disposition** — Control plane / Always tool / Optional tool, from + `primaryDisposition`. + - **Role** — actor role of the fixture (`ic`, `manager`, `reviewer`, + `board_user`, …) from the scenario index (§9 data contract). + - **Claim** — required grants from `requiredGrants` (e.g. + `approval:read`), rendered mono. + - **Parity status** — Pass / Fail / Intentional gap / Not run, from the + parity artifact. + Facets are AND-combined across facets, OR-combined within a facet. Every + facet value shows its live result count; zero-count values stay visible + but disabled (recognition over recall — the vocabulary stays learnable). + An active-filter chip row with per-chip remove and one **Clear filters** + affordance sits above the list (forgiveness). +3. **Case list** — grouped by eval group with sticky group headers. Each row: + case ID (mono, `--pcr-font-size-xs`), title (one line, truncated with + full text in a tooltip), disposition badge, parity status dot+icon. + Selected row uses `--pcr-accent-surface` with a `--pcr-accent` left rule. + +Keyboard: the list is a single-select listbox (`role="listbox"`, +`aria-activedescendant`); Up/Down move, type-ahead jumps, Enter selects and +moves focus to the run header. Facets are disclosure buttons + +checkbox groups. Filter state mirrors into the route (§7) so any filtered +view is linkable; filter state is never stored as protocol state. + +Empty results: “No scenarios match these filters.” + Clear filters button — +never a bare void. + +## 3. Run view (center column) + +### 3.1 Run header + +- Case ID (mono) + title, group badge, disposition badge, assertion-class + badges. +- **Verdict banner** (SDK `Banner`): overall parity verdict for the last + completed run — Pass (success surface), Fail (danger surface), Not run + (muted). The banner names the assertion counts (“12 assertions · 12 pass”) + and deep-links the Parity tab. +- **Mode control:** `Fake agent` (default) / `Codex (bounded)` segmented + control. Fake mode is always available offline. Codex mode appears only + when the local relay is reachable; otherwise the option renders disabled + with the reason (“provider relay not running — see tutorial §4”). The + browser never holds a provider credential; Codex traffic goes through the + same server-side relay boundary proven in Phase 5. +- **Run / Re-run** button and replay controls (SDK `replay-controls`). + Deterministic fixtures mean re-run in fake mode reproduces the identical + timeline; state diffs and parity always describe the displayed run. + +### 3.2 Scenario transcript + +**Source of truth:** the ordered run artifact timeline emitted by the mock +core (§9). Items render in artifact order; the UI never reorders, merges, or +re-times entries. + +The transcript interleaves two visually distinct channels (Similarity + +Common Region — a stranger must tell them apart in two seconds): + +1. **Agent channel** — model turns and semantic tool calls/results. Aligned + with the standard conversation layout (SDK `conversation`/`message`/ + `tool-item`). A semantic tool call renders collapsed by default with a + one-line summary: operation ID (mono) + disposition badge + one-phrase + outcome (“`finish_task` · Always tool · committed”). Expansion is the + item-body / request-detail extension point (§8) and shows: operation ID + and version, argument JSON, result JSON, idempotency behavior, claims the + call required, and redaction chips (§5) — exactly the descriptor fields + from the 7D catalog, never re-labeled. +2. **Control-plane channel** — actions the runtime performed with **no + tool** (checkout, wake routing, budget stops, reconciliation, blocker + wake scheduling…). These render full-width on a `--pcr-muted` surface + with a “Control plane” badge and a gutter glyph distinct from tool items, + and are indented from the agent lane. Copy states the actor plainly: + “Control plane checked out task MCK-102 — no agent tool exists for this.” + Each entry expands to the decision record (inputs considered, resulting + state change, audit reference). + +Failed/denied entries render in place on `--pcr-danger-surface` with the +exact typed denial (§5) — failures are part of the record, never toast-only. + +Restraint/no-call scenarios (`rs-*`, `er-*` restraint cases) must remain +legible when the correct behavior is *absence*: after the final agent turn +the transcript appends a system note “No further operations — N forbidden +operations, none invoked” which deep-links the Parity tab’s forbidden list. +Restraint evidence must never depend on an empty screen. + +PRP events stay behind a per-item “Protocol events” disclosure (same nested +pattern as Phase 5 `debugEvents`) — the semantic view is primary; raw +protocol stays inspectable but secondary (progressive disclosure). + +Auto-follow, jump-to-latest, streaming affordances, and reduced-motion rules +are inherited verbatim from the Phase 4b map §1 — do not redesign them. + +## 4. Inspector tabs (right rail) + +All four tabs are SDK `Tabs`; the active tab mirrors into the route (§7). + +### 4.1 Context + +Answers “who ran, under what authority, with which tools” before any +transcript reading (mental model first): + +- **Actor block:** actor role, task mode, fixture ID (mono), wake payload + summary (reason + trigger), budget posture. +- **Capability grants:** the scenario’s `requiredGrants` plus every grant + the fixture actually issued, rendered as mono chips. +- **Tool exposure list** — the acceptance-critical view. Three labeled + sections, populated **only** from the mock core’s exposure record: + 1. **Always tools (N)** — always-catalog operations visible this run; + 2. **Optional tools (N)** — visible optional operations, each with the + grant that unlocked it (“`decide_approval` — via `approval:decide`”); + 3. **Control plane — no tool (N)** — control-plane-owned capabilities + relevant to this scenario, explicitly listed so reviewers can verify + absence (negative evidence must be visible, not implied). +- **Traceability panel:** source anchor (file:line, mono), skill elements + (file · section · lines), evidence IDs, legacy MCP mapping row if any — + verbatim from the 7A contract. + +### 4.2 Authorization + +Chronological table of every authorization record the mock core emitted: +operation (mono), claims considered, decision (**Allow** / **Deny** with +icon + text), reason string, redactions applied, resulting state change +reference. Row expansion shows the full record JSON. Denied rows use +`--pcr-danger-surface`; a count chip on the tab surfaces denials without +opening it (“Authorization · 1 deny”). Selecting a row scrolls/flashes the +corresponding transcript entry (uniform connectedness across panels). + +### 4.3 State diff + +Before/after immutable snapshot diff for the displayed run, grouped by the +ten entity domains in the plan: **tasks, comments, documents, interactions, +approvals, artifacts, blockers, workspace, budget, run**. Each domain is a +collapsible section headed by a change summary (“tasks · 1 changed”, +“comments · 2 added”); unchanged domains collapse to a single muted row +(“unchanged”) so change carries the visual weight (Von Restorff). Rows show +entity ID (mono) + field-level changes as `field: before → after`, with +added/removed/changed markers as icon + label, not color alone. The diff is +computed by the runtime/test layer and delivered as data; the UI performs no +diffing of its own. A “final state” toggle shows the complete after-snapshot +JSON per domain behind a disclosure. + +### 4.4 Parity + +The eval acceptance surface: + +- **Verdict header** repeating the banner verdict. +- **Assertion list:** one row per conformance assertion — assertion class + badge, human-readable expectation, Pass/Fail, and on fail an expected vs + observed block (mono, side-by-side at desktop, stacked at mobile). +- **Forbidden operations:** each `forbiddenSemantics` entry with “never + invoked ✓” or the violating transcript reference. +- **Intentional gaps:** entries marked as intentional exclusions render + under their own heading with the recorded rationale — visually distinct + from Fail (a gap is a decision, not a defect). +- **Legacy baseline note:** the case’s skill-present/skill-absent reference + note, verbatim, muted — labeled “reference baseline, not the pass + condition.” + +## 5. Credentials, redaction, and denial rendering + +- Fake mode performs zero network I/O; Codex mode talks only to the local + relay; no route, storage key, or bundle string may contain a Paperclip or + provider credential. `localStorage` may hold UI preferences only + (inspector tab, filter collapse state) — never run artifacts, grants, or + anything from a fixture. +- Redacted values arrive pre-redacted from the mock core. The UI renders a + redaction chip: `•••` + “redacted” label + the redaction-rule name in a + tooltip. The UI must not receive-and-hide secrets; if a raw secret ever + reaches the browser payload, that is a 7C/7D defect, and the explorer + additionally fails closed by rendering nothing for fields flagged + redacted. +- A **denied** tool call renders the typed policy denial: operation, the + missing claim, and the denial reason — and never any protected state. An + **absent** tool simply does not appear in exposure lists; the Context tab’s + control-plane section is the affordance proving absence is intentional. +- The generic escape hatch (`paperclipApiRequest` successor), when a test + scenario grants it, renders with a persistent `--pcr-warning-surface` + “test-only escape hatch” banner on every call card (plan §4: visually + flagged). + +## 6. Accessibility, responsive, empty/error states + +Accessibility (WCAG POUR; inherits all Phase 4b/5 baseline rules): + +- Landmarks: `nav` (picker), `main` (run view), `complementary` + (inspector); one `h1`; group headers are `h2`/`h3` in order. +- Full keyboard operation: picker listbox (§2); `F6`/documented shortcut + cycles the three regions; tabs follow the WAI-ARIA tabs pattern + (arrow-key activation); every disclosure is a real `button`. Visible + focus ring via `--pcr-ring` everywhere. +- Live regions: run progress announces via `aria-live="polite"` + (“Scenario run settled — verdict pass”); denial entries announce + assertively once. +- Reduced motion: with `prefers-reduced-motion`, streaming reveal, banner + transitions, and scroll-flash connect cues render instantly/statically + (Phase 5 rule). +- Contrast from the existing token pairs only; parity/authorization + statuses always icon + text. + +Responsive: content-driven single breakpoint at 64rem (§1). At mobile the +inspector tabs become full-width stacked sections inside the Inspect +segment; expected-vs-observed blocks stack; the transcript keeps every +descendant intrinsically shrinkable (`min-w-0` discipline) so no horizontal +scrollbar appears at 390px (Phase 5 finding). + +States that must be designed, not defaulted: + +| State | Surface | Rendering | +| --- | --- | --- | +| No scenario selected | Center + inspector | Explorer intro card: corpus stats (106 cases · 16 groups), “Pick a scenario” pointer at the rail, three example deep links. No dead panels. | +| Scenario selected, not run | Run view | Header + context render from the index; transcript area shows a primed empty state (“Run to produce the deterministic timeline”) with the Run button duplicated inline (Fitts). Diff/Parity tabs show “No run yet.” | +| Run in progress | All | Progress in the header (indeterminate, reduced-motion safe); transcript streams; tabs show live counts; controls disable with reasons. | +| Run failed (harness error) | Run view | Danger banner with the exact diagnostic + “Re-run”; partial timeline stays visible and labeled partial. Never silently reset. | +| Parity fail | Banner/Parity | Fail is a first-class rendered state (danger banner + failing assertion rows) — the explorer’s job is showing it, not avoiding it. | +| Denied/absent tool | Transcript/Context | Per §5. | +| Missing/invalid fixture or artifact | Shell | Error card naming the artifact path and the regenerate command (`pnpm generate:phase7-inventory` / 7E command). No blank screen. | +| Codex relay unavailable | Mode control | Disabled option + reason; fake mode remains fully usable. | + +## 7. Deterministic screenshot routes + +Hash routing (static hosting, no server rewrites): + +``` +#/ explorer home (picker + intro) +#/case/ scenario selected, not run +#/case/?run=fake deterministic fake run, auto-executed +#/case/?run=fake&view= +#/?group=&disposition=&role=&claim=&parity=

&q= filtered picker +``` + +Determinism contract for screenshot/CI use: + +- `run=fake` auto-runs the scenario to completion on load; when the run and + all panels are settled the shell sets `data-run-state="settled"` + (Playwright wait target). Until then it is `pending`. +- Fake runs render **fixture time only** — no wall-clock timestamps, + durations, or locale-dependent formatting anywhere in fake mode; ordering + is by artifact sequence. Two loads of the same route are pixel-identical + at the same viewport (modulo font rasterization). +- `view=` selects the inspector tab (desktop) or segment+tab (mobile); + `view=transcript` closes nothing — it just guarantees focus/scroll starts + at the transcript top. +- Stable `data-testid`s (minimum set): `scenario-picker`, `facet-`, + `case-row-`, `run-header`, `verdict-banner`, `mode-toggle`, + `transcript`, `transcript-item-`, `cp-action-`, + `inspector-tab-`, `exposure-always`, `exposure-optional`, + `exposure-control-plane`, `authorization-row-`, `diff-domain-`, + `parity-assertion-`, `redaction-chip`. + +## 8. Package-local implementation guidance (7F) + +- **Reuse first.** Shell, transcript, and inspector compose the frozen SDK: + `RunnerConsoleApp` is *not* the shell (this is not a chat console); + compose `conversation`, `message`, `tool-item`, `tabs`, `card`, `badge`, + `banner`, `menu`, `dialog`, `tooltip`, `replay-controls` from + `@paperclipai/paperclip-runner/react`. Semantic call detail uses the + item-body renderer (ext point 1); control-plane detail uses the + request-detail renderer contract (ext point 2); theming via scoped + `--pcr-*` overrides (ext point 4). Do not add SDK exports or break the + `0.1.2` freeze — explorer-only components live in the explorer entry. +- **New explorer-local components** (system proposals, one job each): + `ScenarioPicker` (search + facets + listbox), `ExposureList`, + `AuthorizationTable`, `StateDiff` (domain sections + field rows), + `ParityPanel`, `RedactionChip`, `ChannelEntry` (control-plane transcript + entry). Each uses tokens only; any genuinely missing token (e.g. a + `--pcr-diff-*` pair if muted/success/danger surfaces prove insufficient) + is proposed in the 7F PR as a token addition, never inlined. +- **Data contract consumed (owned by 7C/7E, not the UI):** + - *Scenario index* (generated from `eval-traceability.yaml`): `id`, + `title`, `group`, `fixture`, `actorRole`, `taskMode`, + `primaryDisposition`, `requiredGrants[]`, `assertionClasses[]`, + `sourceAnchor`, `skillElements[]`, `evidenceIds[]`, + `forbiddenSemantics[]`. If `actorRole`/`taskMode` are not yet in the + manifest, 7C adds them to the index generator — the UI must not infer + them from prose. + - *Run artifact* (per scenario × mode): ordered `timeline[]` entries + discriminated as `semantic_call` / `semantic_result` / + `control_plane_action` / `protocol_event_ref`; `exposure` (always / + optional-with-grant / control-plane lists); `authorizationRecords[]` + (operation, claims considered, decision, reason, redactions, state-change + ref); `snapshots.before` / `snapshots.after` per entity domain; + `parity` (assertions with class/expected/observed/status, intentional + gaps with rationale, legacy baseline note, verdict). +- **Authority rule (binding):** every rendered fact traces to one of those + records. Grep-able heuristics, UI-side claim math, or re-deriving + dispositions from case IDs are defects. If a view needs a fact the records + lack, extend the record upstream. +- **`DESIGN.md` alignment:** tokens-only values; one component per job; + hierarchy by structure not decoration (domain sections and channels use + surface + position, minimal borders); status vocabulary systematic (§0 + labels everywhere); machine values (IDs, anchors, grants, JSON) in + `--pcr-font-mono`; canonical copy “task.” +- **Testing hooks 7F must ship:** component tests for the four inspector + tabs and both transcript channels; keyboard-path tests (listbox, tabs, + region cycle); reduced-motion test; the §7 route determinism test + (two loads → identical settled DOM); accessibility assertions (landmarks, + names, contrast tokens); screenshot capture script for §9. + +## 9. Screenshot acceptance matrix + +Evidence lands in `knowledge/evidence/phase-07/` as +`-.png`, at both **1440×900** and **390×844**, captured from +the §7 routes after `data-run-state="settled"`. These twelve shots are the +UX acceptance set for 7F (they also cover the plan’s human-checkpoint +scenario families: heartbeat, planning, blockers, approvals, artifacts, +interactions, manager, multi-hop, restraint). + +| # | Slug | Route | Expected visible evidence | +| --- | --- | --- | --- | +| 1 | `explorer-home` | `#/` | Picker with all 16 group facets and counts summing to 106; intro card with corpus stats; no dead panels. | +| 2 | `picker-filtered` | `#/?group=ix&disposition=always_agent_tool&parity=pass` | Active filter chips; filtered count visible; zero-count facet values disabled but legible; Clear filters affordance. | +| 3 | `hb-heartbeat` | `#/case/hb-scoped-wake-01?run=fake&view=transcript` | Control-plane channel entries for scoped-wake routing and checkout (“no agent tool exists for this”), then `get_task_context` agent call; pass banner. | +| 4 | `wk-planning` | `#/case/wk-plan-directive-01?run=fake&view=transcript` | `write_document` call with revision fields, revision-bound `request_human_input` (confirmation), review-parked disposition; no re-plan loop. | +| 5 | `bl-blockers-diff` | `#/case/bl-create-blocked-01?run=fake&view=diff` | State diff: tasks domain shows the new task created blocked; blockers domain shows first-class `blockedByIssueIds`; unchanged domains collapsed. | +| 6 | `ap-approval-denied` | `#/case/ap-mcp-gate-01?run=fake&view=authorization` | Authorization table with a Deny row (missing claim + reason, danger surface, no protected state); “Authorization · 1 deny” tab chip; transcript shows the typed denial card. | +| 7 | `ar-artifacts` | `#/case/ar-upload-before-done-01?run=fake&view=transcript` | `register_deliverable` completing **before** `finish_task` in artifact order; deliverable metadata in the expanded call card. | +| 8 | `ix-interaction` | `#/case/ix-checkbox-01?run=fake&view=transcript` | `request_human_input(kind=checkbox)` call card with options payload; control-plane wake/continuation entry; result inspection entry. | +| 9 | `rf-manager` | `#/case/rf-api-mgr-heartbeat-01?run=fake&view=context` | Context tab: manager role; optional discovery tools listed **with their unlocking grants**; control-plane “no tool” list populated; traceability panel showing source anchor + skill elements. | +| 10 | `mh-multihop` | `#/case/mh-subtask-tree-01?run=fake&view=parity` | Multi-hop assertion rows (child creation, chained blockers) all Pass; forbidden operations section showing “never invoked ✓”. | +| 11 | `rs-restraint` | `#/case/rs-question-only-01?run=fake&view=parity` | Restraint verdict: answer-only transcript with the “No further operations” note; parity forbidden list showing zero state writes; Pass banner. | +| 12 | `rs-secret-redaction` | `#/case/rs-secret-hygiene-01?run=fake&view=transcript` | Redaction chips (`•••` + rule name) in call/result cards; comment content free of the key; parity Pass. | + +Mobile captures use the same routes; the segmented control must show the +correct active segment (`Run` for transcript shots, `Inspect` for tab shots) +and no horizontal scrollbar may be present. + +Acceptance procedure: UXDesigner reviews all 24 images against this matrix +before 7F is accepted (plan §6: “UXDesigner supplies the interaction map and +reviews screenshots before implementation acceptance”). Any deviation is +either fixed or written into this document as a revision — silent divergence +fails the gate. + +## 10. Out of scope / rejected + +- No second app shell, no Tailwind/Radix, no dark mode, no markdown + renderer, no command palette, no transcript virtualization — Phase 5 + rejections stand. +- No editing affordances of any kind: fixtures, grants, and policies are + changed in code/YAML, not in the browser. The mode toggle and run/replay + controls are the only mutating-looking controls, and they mutate only the + in-browser demo run. +- No parity “re-judging” in the UI: the Parity tab renders 7E output; it + never recomputes assertions. +- No live-Paperclip or ACPX affordances; the future binding boundary stays a + docs note, not a UI surface. diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/mockup-explorer-ap-mcp-gate-1440x900.png b/packages/paperclip-runner/knowledge/evidence/phase-07/mockup-explorer-ap-mcp-gate-1440x900.png new file mode 100644 index 00000000000..bc6aac0e3fd Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/mockup-explorer-ap-mcp-gate-1440x900.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/mockup-explorer-ap-mcp-gate-390x844.png b/packages/paperclip-runner/knowledge/evidence/phase-07/mockup-explorer-ap-mcp-gate-390x844.png new file mode 100644 index 00000000000..3bb7e1e493c Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-07/mockup-explorer-ap-mcp-gate-390x844.png differ diff --git a/packages/paperclip-runner/scripts/shot-phase7-mockup.mjs b/packages/paperclip-runner/scripts/shot-phase7-mockup.mjs new file mode 100644 index 00000000000..e2b3995505b --- /dev/null +++ b/packages/paperclip-runner/scripts/shot-phase7-mockup.mjs @@ -0,0 +1,16 @@ +import { chromium } from "@playwright/test"; + +const exe = "/srv/paperclip/home/paperclipai/paperclip/.paperclip/browser-runtime/chromium-arm64/bin/chromium-agent-browser"; +const url = "file:///srv/paperclip/home/paperclipai/paperclip/.paperclip/worktrees/PAP-16679-paperclip-runner/packages/paperclip-runner/docs/design/mockups/phase-7-scenario-explorer.html"; +const out = "knowledge/evidence/phase-07"; + +const browser = await chromium.launch({ executablePath: exe }); +for (const [w, h, tag] of [[1440, 900, "1440x900"], [390, 844, "390x844"]]) { + const page = await browser.newPage({ viewport: { width: w, height: h } }); + await page.goto(url); + await page.waitForTimeout(400); + await page.screenshot({ path: `${out}/mockup-explorer-ap-mcp-gate-${tag}.png` }); + await page.close(); +} +await browser.close(); +console.log("done");