Detail pane states — one family, re-applied

Every state the detail pane can show, sorted into five groups by what the researcher can do about it. The Mac draws each one with the stock ContentUnavailableView that eight panes already use: an icon, a headline, one line of body, and at most one action. Where bristlenose serve has a twin, the browser frame shows the shipped status page. Nothing here is a new component. What changes is the words and the icon in each slot. Every changed string is outlined, and the string table in §5 lists them all in one place.

Artefact — what shipsCommentary — whyProposed string (owner to word)
Commentary — the rule this applies

1 · The five groups

Group 1 — Nothing here yet

N00 · no selection

Drop a folder of recordings or transcripts

Bristlenose adds the folder as a project.

N04a · empty project

Drag interviews here

Recordings or transcripts.

N04b · files waiting (keep)

6 files to analyse

Analyse
N10 · several projects selected

3 projects selected

Choose one to see its report.

W02 · browser, never analysed (CLI)
localhost:8150/report/

This folder hasn’t been analysed yet

$ bristlenose run interviews/

Commentary — group 1

Group 2 — Working

Boot · starting / loading report — bar only (decided, keep)
Queued · cover over a stale status page

Queued · position 2

Starts when the analysis before it finishes.

Analysing · cover, animation preference off or Reduce Motion

Transcribing · 3 of 8 · ~12 min left

The report opens as soon as the first interview is readable.

Analysing · the shoal, animation preference on (decorative, keep)
W-IP · browser, analysis in progress
localhost:8150/report/

Analysing interviews

Commentary — group 2

Group 3 — Needs you

N02 · folder moved or deleted

Can’t find this project’s folder

It may have been moved, renamed or deleted. If you know where it is, point Bristlenose at it.

Locate…
Refused · no AI provider set up

Choose an AI provider to analyse this project

Bristlenose sends the transcripts to an AI provider such as Claude or ChatGPT. Pick one in Settings.

Set Up Provider…
Stopped · the researcher stopped it, no earlier report (with one, the pane shows that report — Q4)

Analysis stopped

Resume Analysis
W03 · browser, stopped
localhost:8150/report/

Analysis stopped

Commentary — group 3

Group 4 — Can’t reach it

N01 · drive not connected

“Samsung T7” isn’t connected

Reconnect to continue.

N01n · network share unreachable

“server.local” can’t be reached

Reconnect to continue.

Stranded · the run lost its process

The analysis stopped before it finished

The app quit, or the Mac lost power.

Resume Analysis
W-stranded · browser
localhost:8150/report/

The analysis stopped before it finished

N08 · analysis engine failed to start — plain family (decided Q2; buttons: docs/design-feedback-native.md § “Feedback and problem reports” (mockup n08-button-set.html))

Couldn’t start Bristlenose

Bristlenose stopped before it finished starting (code 1).

RetryShow details
Report crash · keep (decided 20–21 Oct)
Commentary — group 4

Group 5 — It broke

Failed · the run failed; the remedy decides the button

The analysis didn’t finish

Claude wouldn’t accept the API key. Check it in Settings ▸ LLM Provider.

Set Up Provider…Show details
W04 · browser, failed
localhost:8150/report/

The analysis didn’t finish

Claude wouldn’t accept the API key.

Show details
category: auth
W05 · build incomplete (dev only) — today
localhost:8150/report/

Build incomplete

The Bristlenose React bundle is missing from this build. Serve mode refuses to start without it.

If you are running the desktop app, this build is broken — reinstall or report a bug.

If you are a developer: run npm run build in frontend/ and restart bristlenose serve.

W05 · restyle only — same English, status-page template
localhost:8150/report/

Build incomplete

The Bristlenose React bundle is missing from this build. Serve mode refuses to start without it.

Show details
If you are running the desktop app, this build is broken — reinstall or report a bug.

If you are a developer: run npm run build in frontend/ and restart bristlenose serve. If running from the PyInstaller sidecar, check that bristlenose/server/static/ is in the spec’s datas.

BUG-3 class — see the C3 smoke test post-mortem for context.
Commentary — group 5

2 · Before and after — the four worst

2.1 · iCloud — removed 22 Oct 2026: the in-iCloud pane was deleted (bbf75243), so there is no before or after. A gone cloud folder is N02; policy docs/design-cloud-files.md.
2.2 · Refused run — before: the reason is only on the row
before — the pane is the serve’s status page

Not analysed yet.

after — the popover’s reason, and its existing door

Choose an AI provider to analyse this project

Bristlenose sends the transcripts to an AI provider such as Claude or ChatGPT. Pick one in Settings.

Set Up Provider…
2.3 · Failed run — before: two vocabularies for one state
before — pane (serve’s status page)

Last run failed.

Error code: 401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}}

Show details
category: auth
before — the row’s popover
Run failed
Show Log

Your Claude key was rejected.

Provider key issue

after — pane

The analysis didn’t finish

Claude wouldn’t accept the API key. Check it in Settings ▸ LLM Provider.

Set Up Provider…Show details
after — the row’s popover, same sentence
Run failed
Show Log

Claude wouldn’t accept the API key. Check it in Settings ▸ LLM Provider.

Provider key issue

2.4 · Analysis engine failed to start (BootView) — decided Q2: option B, the plain family
before / option A — brand block kept

Bristlenose

Sensemaking for User Research

Couldn’t start Bristlenose

Bristlenose stopped before it finished starting (code 1).

RetryShow details
option B — the plain family

Couldn’t start Bristlenose

Bristlenose stopped before it finished starting (code 1).

RetryShow details
Commentary — §2

3 · The analysing pane — queued, transcribing, then the report

1 · queued behind another study

Queued · position 2

Starts when the analysis before it finishes.

2 · transcribing — the row’s line under the ring

Transcribing · 3 of 8 · ~12 min left

The report opens as soon as the first interview is readable.

3 · first interview readable — the pane hands over to the Sessions lens
p1
p2
p3
p4
p5
p6
Commentary — §3

4 · Icon sheet — SF Symbol and its Lucide twin, one concept each

ConceptSF Symbol (Mac)Lucide (browser)Used byToday
Empty — add interviews tray.and.arrow.down inboxN00, N04a, N04bsquare.and.arrow.down on N04
Several selected square.stack layersN10same
Queued clock clockQueued coversame
Workingno icon — the run ring takes the slotAnalysing coverwaveform
Folder moved questionmark.folder folder-searchN02same
Needs a provider key key-roundRefused— (status page ℹ)
Stopped stop.circle circle-stopStopped— (status page ⚠)
Drive not connected externaldrive.badge.xmark hard-driveN01externaldrive.trianglebadge.exclamationmark
Share unreachable network.slash wifi-offN01nthe drive’s icon
Stopped unexpectedly / failed exclamationmark.triangle triangle-alertStranded, Failed, N08 (option B)— (status page ⚠ / ✗; N08 the app icon)
Commentary — §4

5 · String table — edit the English here

E existing key, reworded   N new key (the suggested key name is in amber)   K keep as shipped. Each E or N row is a change across 21 locales.

StateElementKeyCurrentProposed
Group 1 — Nothing here yet
N00 no selectionheadlinedesktop.welcome.dropFolderTitleDrop a folderDrop a folder of recordings or transcriptsE
bodydesktop.welcome.dropFolderHintDrag a folder of recordings or transcripts here to add it as a project.Bristlenose adds the folder as a project.E
N04a emptyheadlinedesktop.chrome.dragInterviewsDrag Interviews HereDrag interviews hereE
bodydesktop.chrome.dragInterviewsDescriptionAdd interview recordings or transcripts to get started.Recordings or transcripts.E
N04b files waitingheadlinedesktop.chrome.filesToAnalyse_one / _other1 file to analyse / {{count}} files to analyse—K
actiondesktop.menu.project.analyseAnalyse—K
N10 multi-selectheadlinedesktop.chrome.multipleSelected%d items selected{{count}} projects selected (becomes a plural set, _other etc.)E
bodydesktop.chrome.multipleSelectedHintSelect a single project to view its report.Choose one to see its report.E
W02 CLI, never runheadlineserver.statusPage.noRunCliShortNothing to see here, yet.This folder hasn’t been analysed yetE
bodyliteral, not localised$ bristlenose run interviews/—K
Group 2 — Working
Boot—desktop.boot.startingSidecar / loadingReportnot drawn (bar only)—K
Queuedheadlinedesktop.chrome.pipeline.queuedPositionQueued · position {{position}}—K
bodydesktop.chrome.pipeline.queuedHint(none)Starts when the analysis before it finishes.N
Analysingheadlinedesktop.chrome.pipeline.analysing → RunProgressSubtitle (stage.* · sessionsCount · etaMinutes)Analysing…the row’s own line, e.g. Transcribing · 3 of 8 · ~12 min left — no new keyK
bodydesktop.chrome.pipeline.analysingHint(none)The report opens as soon as the first interview is readable.N
W-IP in progressheadlineserver.statusPage.inProgressShortAnalysing…Analysing interviewsE
Shoal——no text—K
Group 3 — Needs you
N02 movedheadlinedesktop.chrome.projectMovedProject Moved or DeletedCan’t find this project’s folderE
bodydesktop.chrome.projectMovedDescriptionThe project folder couldn’t be found. It may have been moved or deleted.It may have been moved, renamed or deleted. If you know where it is, point Bristlenose at it.E
actiondesktop.chrome.locateLocate…—K
Refused, no providerheadlinedesktop.chrome.providerNeeded (pane today: server.statusPage.noRunDesktopHasInterviews)Not analysed yet.Choose an AI provider to analyse this projectN
bodydesktop.chrome.providerNeededHint(none — the reason is only on the row: “Provider not set up”)Bristlenose sends the transcripts to an AI provider such as Claude or ChatGPT. Pick one in Settings. (two examples, not the list — decided Q6)N
actiondesktop.pipeline.diagnostic.action.setUpProviderSet Up Provider… (popover only)— (reused in the pane)K
Stoppedheadlineserver.statusPage.cancelledShort (+ desktop.chrome.stoppedTitle for the native pane)Last run was cancelled.Analysis stoppedE
bodyserver.statusPage.cancelledLongRe-run when ready.— no body; the key is retiredE
actiondesktop.chrome.resumeAnalysis—Resume Analysis (the same key as the stranded button; Analyse after a stop resumes from the partial output, adaa97e5)N
Group 4 — Can’t reach it
N01 driveheadlinedesktop.chrome.projectUnavailable + the volume name as a second lineProject Unavailable / Samsung T7“{{name}}” isn’t connectedE
bodydesktop.chrome.projectUnavailableHintConnect the drive to access this project.Reconnect to continue.E
N01n network shareheadlinedesktop.chrome.shareUnreachable(the drive’s: Project Unavailable / server.local)“{{host}}” can’t be reachedN
bodydesktop.chrome.projectUnavailableHintConnect the drive to access this project.Reconnect to continue. (the drive’s key: one body for both)K
Strandedheadlineserver.statusPage.strandedShort · desktop.pipeline.failure.strandedAnalysis stopped unexpectedly.The analysis stopped before it finishedE
bodyserver.statusPage.strandedLong (+ desktop.chrome.strandedHint, the Mac form)Re-run when ready.Mac: The app quit, or the Mac lost power.
Browser: — no body; strandedLong is retired
E
actiondesktop.chrome.resumeAnalysis—Resume Analysis (Analyse after a stranded run resumes from the partial output, adaa97e5; the menu item for the same command stays Analyse)N
N08 engine failedheadline · reason · buttonsdesktop.boot.failedTitle · boot.failure.* · boot.retry · boot.showDetailsCouldn’t start Bristlenose · e.g. Bristlenose stopped before it finished starting (code 1). · Retry · Show details—K
taglinedesktop.boot.taglineSensemaking for User Researchno longer drawn here (option B, decided Q2)K
Report crashbody · buttoncommon.labels.reportError · buttons.retryThis report couldn’t be shown. · Retry— (settled 20–21 Oct)K
row · popoverdesktop.pipeline.diagnostic.header.reportError · desktop.pipeline.diagnostic.reportErrorReport couldn’t be shown · Your analysis is safe — only the display failed. …— (settled)K
Lens / part crashbodycommon.labels.lensError · common.labels.partErrorThis lens couldn’t be shown. Try again, or choose another lens. · This couldn’t be shown.— (settled)K
Group 5 — It broke
Failedheadlineserver.statusPage.failedShort (+ desktop.chrome.failedTitle)Last run failed.The analysis didn’t finishE
bodytoday: raw cause.message; proposed: the popover’s reason key, e.g. desktop.pipeline.failure.authError code: 401 - {'type': 'error', …} (provider’s raw text). The popover today says: Your {{provider}} key was rejected.Claude wouldn’t accept the API key. Check it in Settings ▸ LLM Provider. (from analysis-failure-states.html § D; one sentence per cause, read by both the popover and the pane; the browser drops the Settings clause)E
actiondesktop.pipeline.diagnostic.action.setUpProvider · desktop.boot.retry—Set Up Provider… or Retry, by remedyK
disclosureserver.statusPage.showDetails · desktop.boot.showDetailsShow details—K
W05 build incompletepageapp.py literal (dev only)Build incomplete + three paragraphs— (restyle only)K
Commentary — §5

6 · Questions for you — answered 24 Oct 2026

Commentary — decisions this mockup needed, with the owner’s answers
  1. Native or unified copy only? Should the Mac take over the failed, stopped and stranded panes natively, as drawn? The alternative keeps the serve’s status page in the pane and only unifies its words with the popover’s.
    Answer: native, as drawn. The Mac draws failed, stopped, stranded and refused with ContentUnavailableView; the browser keeps the status page with the same words.
  2. Brand on the engine-failed pane? Should it keep the app icon, wordmark and tagline (option A), or join the plain family (option B, §2.4)?
    Answer: option B, the plain family. Starting is already bar-only, so no pane keeps the brand block. N08’s buttons are decided elsewhere: docs/design-feedback-native.md § “Feedback and problem reports” (mockup n08-button-set.html).
  3. Casing. Should Mac pane headlines be sentence case, with Title Case kept for buttons only?
    Answer: sentence case, no full stop; buttons Title Case. The HIG’s Writing page asks for one style per element type, used consistently; its Alerts page (fragment → Title Case, sentence → sentence case with a stop) was considered and not taken.
  4. Stopped. Should it show a neutral pane with Analyse, or show the previous report when one exists?
    Answer: the previous report when one exists, the row saying Stopped; the neutral “Analysis stopped” pane with Resume Analysis only when there is no report. This is D4-B for cancelled runs only (docs/design-project-condition.md §6.1); D4 for failed runs is not decided here.
  5. Pane and row wording. May a pane headline differ from the row’s sentence for the same state? For example “6 files to analyse” beside “6 files not analysed”, or “Choose an AI provider…” beside “Provider not set up”.
    Answer: yes — the wording may differ, the fact may not. The row is the status, the pane the instruction; queued and analysing keep the row’s own line.
  6. Naming providers. May the no-provider sentence name the four providers? Each new provider would then mean a copy change in 21 locales.
    Answer: two examples, not the list — “Bristlenose sends the transcripts to an AI provider such as Claude or ChatGPT. Pick one in Settings.” It stays true as providers are added, and with Local.
  7. Multi-select. Should the multi-select pane stay a dead end, as drawn (no action)?
    Answer: a dead end, as drawn. Actions on several projects stay in the sidebar’s context menu and the Project menu.
Commentary — owned elsewhere, linked not duplicated