Skip to content

feat: implement the IMPROVEMENTS.md backlog (all 50 items) - #43

Merged
scotej merged 13 commits into
mainfrom
feat/improvements-backlog
Jun 12, 2026
Merged

feat: implement the IMPROVEMENTS.md backlog (all 50 items)#43
scotej merged 13 commits into
mainfrom
feat/improvements-backlog

Conversation

@scotej

@scotej scotej commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

Implements every item in IMPROVEMENTS.md (F1–F10, U1–U7, S1–S4, A1–A6, D1–D7, R1–R7, X1–X7, N1–N6, P1–P2) across 12 commits. Final accounting: 0 partial, 0 missing; 9 items landed adapted with documented rationale. The accepted deviations I9/I18 are untouched per the working agreement.

Highlights by area:

  • Friend-finding reliability — relay-down failures are finally legible ("can't reach the network" vs "friend hasn't arrived"), per-relay diagnostics panel, user-configurable relay URLs + TURN server (no rebuild needed), invite retry on presence with dedupe, near-instant offline via a wire-compatible presence goodbye, studyvis:// as a real OS deep link (prefill, never auto-connect).
  • Session robustness — 20s grace window before auto-end on transient disconnects, PTT can no longer latch the mic open across sessions (privacy fix, PLAN §5), camera toggle that also pauses the AI loop, audio-output picker + per-peer volume, per-peer connection states in the grid, waiting-for-friend tile, confirm-before-quit mid-session (incl. a custom macOS menu quit item — NSApp.terminate can't be intercepted).
  • AI honesty — benchmark/live/eval requests share one builder; malformed responses count as uncertain (never fake on_task); off-task judgments gated on an on_topic_confidence floor (Settings slider, default 0.6); duration-based thermal cadence backoff; sidecar port re-read before POST; resumable model downloads (HTTP Range) with an honest Resume affordance.
  • Honest stats & insights — AI-off sessions persist score=null instead of a fabricated 100; cross-session focus-insights view (distraction timing, recurring reasons, trend); report/CSV/audit-log file exports; session delete + clear-all history.
  • Identity safety — corrupt identity loads can never steer into create-new onboarding; create refuses to clobber existing keychain keys; recovery detects same-vs-different mnemonics; friends-list backup/restore (SVFB v2: sealed to the user's X25519 key and Ed25519-signed so backups aren't forgeable by friends).
  • Notifications & pomodoro — break/work OS notifications (opt-out), friend-online notifications (opt-in), custom pomodoro durations with a backward-compatible wire (old peers render legacy presets, tested against a frozen copy of the shipped parser), optional chime (opt-in), opt-in version check (OFF by default; PLAN §3 amended with the carve-out).
  • Release & CI — release-prep gated on lint/test/build/tokens/strings/contrast/rustfmt before tagging; check-strings in CI; ad-hoc macOS signing with hardenedRuntime: false (the default would have broken sidecar dylib loading in release builds); dormant updater removed; single-instance guard; graceful corrupt-DB recovery + newer-schema refusal at startup.
  • A11y gate hardeningcheck-contrast now scans every token co-occurrence (cva variants, modifier-prefixed classes included) and fails on combos missing from the allowlist.
  • Docs — PLAN/ARCHITECTURE/DESIGN-SYSTEM/INSTALL/README/ISSUES/CHANGELOG reconciled with reality (STUN-only truth, plaintext-at-rest threat-model row, Linux unblock checklist, credential-gated signing roadmap, Intel claim dropped per decision).

Every cluster went through implement → gates → 3-lens adversarial review with per-finding verification → advisor pass → fix, plus a 6-lens whole-branch review at the end. Notable catches that would have shipped otherwise: the hardened-runtime sidecar blocker, the dead Cmd+Q intercept, trystero's onJoinError never firing for blocked relays (backlog premise corrected), a custom-relay boot race against settings hydration, an R7 wire-shape bug invisible to fixture-based tests, and forgeable friend backups.

Test plan

Machine-verified (all green on the branch):

  • npm run build, lint, test (600 tests, ~170 added), check-tokens, check-strings, check-contrast (incl. new coverage scanner), format:check
  • build-storybook + check-a11y (247 axe checks)
  • cargo test && cargo fmt --check && cargo clippy in src-tauri/
  • Wire-compat unit tests run new payloads against frozen copies of the shipped parsers (pomodoro, presence)

User walks recommended before merge (not yet machine-walkable):

  • Windows installed MSI: studyvis://pair link with app closed and running — prefill only, never auto-connect
  • macOS: fresh ad-hoc-signed DMG — Gatekeeper matches INSTALL.md; TCC camera/mic/screen grants persist across relaunch (signature change may invalidate v1.2.0 grants)
  • Cross-version session vs a v1.2.0 build: custom pomodoro both directions; hard-quit goodbye
  • Corrupt-DB walk: truncated app.db → recovery dialog; schema_version=99 → "update needed" with file untouched

🤖 Generated with Claude Code

scotej and others added 12 commits June 12, 2026 21:14
X1 — release-prep now runs lint, test, build, check-tokens,
check-strings, and cargo fmt --check in a gate job before any
version bump, tag, or push lands on main.
X3 — ci.yml frontend job runs check-strings next to check-tokens
so the strings-module house rule has a CI backstop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The new-version check (OFF by default) is the one sanctioned
outbound request beyond P2P + Nostr signaling: an unauthenticated
GET to the public GitHub Releases API carrying no identifiers,
no query parameters, and no payload; failures are silent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
N1 — single-instance guard; relaunch focuses the existing window.
F10 — studyvis:// registered as an OS deep link (plugin config,
capability, argv forwarding; subscribePairDeepLink helper lands
unwired until the friends cluster routes it into the accept flow).
N4 — quit-confirm scaffolding: SessionActiveFlag, session_set_active,
app_quit, quit-requested event; macOS Cmd+Q rerouted through a
custom menu item since NSApp.terminate can't be intercepted.
D2 — corrupt app.db is set aside and recreated with an explanatory
dialog instead of a startup panic; healthy-but-unopenable data is
never destroyed.
D6 — a DB created by a newer build is refused with a distinct
'update needed' dialog, no rename/recreate.
R4 — sessions_delete / sessions_clear_all commands (tx-scoped,
audit events included).
D3 — friends_export / friends_import commands (sealed-box to the
user's own X25519 key, SVFB v1 format, upsert on import).
A4 — model downloads resume via HTTP Range from the surviving
.tmp, hasher seeded from existing bytes.
X4 — system_fetch_latest_version command (bare GET, no
identifiers, 10s timeout; UI toggle ships OFF by default later).
X5 — ad-hoc signingIdentity '-' with hardenedRuntime false so the
sidecar's DYLD-based dylib resolution survives release signing.
X6 — dormant tauri-plugin-updater removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ath, confidence floor, cadence backoff, resume affordance

A1 — benchmark, live loop, and the ai-eval harness all build their
chat request through one shared focusRequest builder (two images,
same system prompt, max_tokens, response_format); the benchmark's
screen slot is letterboxed to live capture width so Qwen's
dynamic-resolution prefill is no longer understated.
A2 — malformed/empty model responses become an internal 'uncertain'
verdict: streak and latches untouched, sample excluded from
focusedPct via a separate skipped tally; 'uncertain' provably never
reaches the signed ai-alert wire or the audit vocabulary.
A3 — off-task judgments carrying >= floor on-topic confidence are
skipped as uncertain; floor persisted as off_task_confidence_floor
(default 0.6) with a Settings -> AI slider (UI min 0.05; 0 stays a
programmatic disable).
A5 — the tick re-reads the sidecar port after the capture await and
bails/reschedules when the watcher respawned the server.
A6 — duration-based cadence backoff (2 slow ticks engage x2 interval,
3 normal ticks recover) with a one-shot in-voice notice; replaces the
dangling 'thermal-aware notice' comment.
A4 — interrupted downloads persist their real byte offset (terminal
events hardcode 0; the container stashes downloading-phase counts)
and the picker shows an honest 'Resume download' affordance.

487 unit tests pass (35 added); tsc/lint/tokens/strings/prettier green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, camera toggle, output audio, connection states, quit confirm

S1 — a 20s grace window before auto-ending when the room empties;
any rejoin cancels it, seenPeerEdPubkeys survives the gap, and
buildLeaveHandler's alreadyLeft latch stays the one idempotency point.
S2 — PTT can no longer latch the mic open: pttStore.reset() on every
session start/teardown (host/join/SessionView), plus a 120s stuck-key
guard tuned for macOS global hotkeys (no key-repeat events); a stale
latch can never bring a fresh session's first audio track up live.
R1 — snapshotFocusForReport returns score:null when no confident
samples exist; the report renders a calm no-score state instead of a
fabricated 100/100 gauge and stats averages skip nulls.
S3 — camera on/off toggle flips track.enabled (stream stays monotonic),
broadcasts a backward-compatible camera-state action so peers render
an explicit camera-off tile, and pauses the AI loop without counting
ticks against the user.
S4 — audio output picker (feature-detected; hidden on macOS WKWebView)
and a per-peer local-only volume slider.
U2 — a §10-pattern waiting tile when alone in an active session.
F4 — per-peer RTCPeerConnection state surfaces as connecting/failed
tile badges; transient 'disconnected' stays 'connecting', no TURN.
N4 — session_set_active wired at one status-keyed chokepoint and a
quit-requested listener with an in-app confirm dialog backing the
wave-1 Rust scaffolding.

504 unit tests pass (17 added); all frontend gates green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…retry, presence goodbye, OS deep link

F1 — relay-down detection driven by the live socket map
(relaysUnreachable): the pairing dialog's 30s hint now distinguishes
'can't reach the network' (your side) from 'friend hasn't arrived';
onJoinError is forwarded through the wrapper and correctly mapped to
handshake failure, which is the only thing trystero fires it for.
F2 — NetworkCategory connection panel: per-relay state rows polled
while visible, state shown by glyph + text, never color alone.
F3 — user-supplied relay URLs and a TURN server persist in settings
and flow through the existing relayConfig/buildIceOptions seams; URL
validation mirrors new WebSocket() so a malformed saved relay can't
white-screen the boot (inbox/presence joins also guarded); the
turnPreference radio finally does something when TURN exists.
F5 — 45s post-peer-arrival stall timer: 'connected to the network
but couldn't establish a direct link' with a pointer to relay/TURN
settings.
F6 — invites re-attempt when the friend flips online within the
retry window, deduped per recipient+session so a friend can never
receive the same invite twice; offline-friend vs relay-down failures
read differently.
F7 — best-effort goodbye on quit flips presence offline immediately;
wire-compatible both directions (goodbye omits ts so older receivers
drop it and age out via the 60s window; I2 receiver-clock intact).
F9 — QR error correction M→Q, larger module size, and a freshness
note for the ~10-minute secret.
F10 — OS-delivered studyvis://pair links prefill (never auto-connect)
the join form; a second link can't discard a half-typed code.
F8 — settings copy, README, PLAN §2/§7, and ARCHITECTURE stop
promising a public TURN fallback that no longer ships.

540 unit tests pass (36 added); build, tsc, lint, tokens, strings,
contrast, prettier all green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eletion

R7 — local-only focus-insights section in the stats dashboard:
when-distractions-happen timing buckets anchored on session start,
recurring distraction reasons aggregated across sessions (lifting
reportData's per-session aggregation), and a focused-time/score trend
chart; data shaped in a pure statsInsights seam reading audit_events
via a new audit_events_list_all command.
R3 — 'Save as…' for the report (markdown), a per-session raw audit
JSON dump, and a stats CSV of daily study minutes + partner counts,
all through the system save dialog and a new system_write_text_file
command (no fs-plugin surface added).
R4 — per-session delete (SessionsCategory, confirm dialog) and
clear-all-history (AdvancedCategory, stronger confirm) over the
wave-1 sessions_delete/sessions_clear_all commands; lists refresh
after deletion.
R2 — stats label renamed 'Study minutes'; 'Focused' is reserved for
the AI on-task concept.
R5 — serialized report sections now match the on-screen order.
R6 — the average-score tile says how many sessions it covers
('from N of M sessions') with a muted limited-data state.

Review caught and fixed a wire-shape blocker: AuditEventRecord
declared camelCase sessionId against serde's snake_case session_id,
which would have left the timing section permanently empty while
fixture-based tests passed.

567 unit tests pass (27 added); a11y suite 242 axe checks green;
cargo + all frontend gates green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g back, friends backup UI

D1 — a corrupt/unreadable identity.json routes to a calm error screen
(Retry + Restore) and can never reach create-new onboarding; the
commit path is double-guarded (frontend re-check + identity_save_keys
overwrite flag in Rust) so create refuses to clobber keychain keys,
with steering copy toward Restore when orphaned keys exist.
D4 — the dead 'Recovery phrase' settings row is honest (24 words
can't be re-shown, by design) and actionable: 'Restore a different
identity' opens the existing Recover flow from Settings.
D5 — recovery compares the typed words' fingerprint to the stored
one: same words skip the warning, unknown gets the generic confirm,
different words get escalated replace-identity copy; the done screen
no longer tells same-identity users to re-pair, and a Settings
restore preserves the display name instead of silently blanking it.
D3 — Export/Import friends buttons (sealed .svfriends backup via the
wave-1 commands), different-identity decrypt errors mapped to
friendly copy, list refreshes after import, zero-friends export
writes nothing.
U1 — invite button always visible (outline at rest, accent on
hover/focus) instead of hover-only.
U3 — onboarding gains Back per the §8.1 wireframe, suppressed once a
mnemonic is committed.
U4 — zero-friends empty state keeps one CTA.
U6 — SessionTimer presets use the RadioGroup primitive (themed focus
ring, arrow-key nav).

572 unit tests pass; cargo, a11y (246 axe checks), and all frontend
gates green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s, custom durations, audio cue, opt-in version check

N2 — OS notification on local work↔rest boundaries (opt-out, ON by
default), suppressed while the window is visible and focused; reuses
the InboxBoot permission pattern; no I9 protocol change.
N3 — 'friend came online' notification (opt-in, OFF by default),
baseline-aware so boot sweeps, resubscribe ticks, and 60s-window
flapping never fire it; help copy honest about presence latency.
N5 — custom pomodoro durations (5–120 work / 1–60 rest) with a
backward-compatible wire: explicit work_ms/rest_ms ride alongside a
strictly-legacy preset fallback, so old peers render legacy timings
and never see 'custom'; new receivers prefer explicit durations; a
90/20 handover survives a broadcaster drop without retiming. Compat
matrix tested against a frozen copy of the shipped parser.
N6 — gentle two-note chime on phase transitions (opt-in, OFF by
default), 1.7KB opus inlined as a data URI per the V2-P6 pattern.
X4 — 'Check for new versions' toggle (OFF by default) in About; when
on, a single bare GET on mount compares tags and shows a quiet
update row; zero outbound while off, silent on failure (PLAN §3
carve-out).

600 unit tests pass (4 suites added); a11y 247 checks, build with
inlined chime verified, all frontend gates green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… (U5)

scripts/check-contrast.ts gains an AST-based coverage scanner: every
text-*/bg-*/border-* token co-occurrence in src/ (plain className,
cn()/cva() args incl. variant objects and ternary arms, template
literals, modifier-prefixed classes like hover:/focus-visible:/
data-[state]:) must have a PAIRINGS entry or the script fails,
naming the file, the combo, and the fix path. A narrowly-scoped
IGNORED_COOCCURRENCES list (file + combo + required reason, stale
entries fail) handles cross-state false adjacencies.

Surfaced 18 unlisted real pairings across the earlier clusters — all
added and AA-verified in both themes (idle hairline borders stay
informational per WCAG 1.4.11). Review probes confirmed the scanner
catches planted violations in all class-shape forms and that cva
variants and hover-prefixed utilities — the two proven blind spots —
are now visible.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PLAN — Linux deferral becomes a concrete unblock checklist and the
signing/notarization/auto-update stack is one credential-gated
roadmap item (trigger: certs acquired), both under a new deferred-
scope section; §3 carve-out verified against the shipped X4.
ARCHITECTURE — plaintext-at-rest threat-model row (§14); the
implemented cadence backoff + uncertain-skip replace the dangling
thermal-notice claim (§8); camera-state, pomodoro work_ms/rest_ms,
and presence goodbye join the wire inventory with compat rationale
(§7); invite retry vs relay-down distinction (§6); cross-session
audit reads for focus insights (§9); new plugins and the nine new
IPC commands inventoried (§2/§11).
DESIGN-SYSTEM — stale BipBackupPanel note fixed (U7); new visual
components added to the §4 inventory.
INSTALL/README — Intel x64.dmg claim dropped (Apple Silicon only);
Gatekeeper language softened for ad-hoc-signed builds, xattr
quarantine fallback kept.
ISSUES — I19 Sev4: npm-audit advisories are dev-chain only
(npm audit --omit=dev is clean), count-free so it doesn't go stale.
CHANGELOG — Unreleased section covering all eight clusters with
their settings defaults.

Audit pass cite-checked every claim against the committed code;
stale counts and a wrong ON CONFLICT column name were corrected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…backups, DB lock safety

F3 boot race (major) — boot-mounted presence/inbox joined trystero
before async settings hydration, and trystero pins its relay sockets
on the first joinRoom for the process lifetime, so saved custom
relays were silently ignored on most boots. InboxBoot now waits for
settings hydration before the first join.
friends_import authenticity (major) — a sealed box proves
confidentiality, not authorship: any friend holding the user's
X25519 pubkey could mint an importable backup and hijack x_pubkeys
via the ed_pubkey upsert. SVFB v2 Ed25519-signs the payload with the
user's own key and import verifies it; per-row pubkey validation and
a 10k-row cap added. v1 never shipped, so no migration.
DB lock split-brain (advisor) — the corruption probe now only
declares corruption on an actual non-ok integrity_check verdict; a
locked/busy DB bails as unrecoverable instead of being renamed and
recreated.
PTT re-acquire (minor) — the S2 reset moved off the media-retry
effect so a mid-hold 'Try again' re-acquire keeps the documented
unmuted contract; leave/auto-end/unmount resets unchanged.
Doc/CI residues — PLAN §2 Apple-Silicon-only wording, release-notes
body reflects ad-hoc signing, release-prep gate gains check-contrast.

All gates green: 600 vitest, build, lint, tokens, strings, contrast,
prettier, storybook a11y, cargo test/fmt/clippy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 12, 2026 23:16
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 169 files, which is 19 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 34f0f1af-c30c-4abb-9d7c-8e4de3ece98f

📥 Commits

Reviewing files that changed from the base of the PR and between eda9593 and d21780d.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (169)
  • .github/workflows/ci.yml
  • .github/workflows/release-prep.yml
  • .github/workflows/release.yml
  • ARCHITECTURE.md
  • CHANGELOG.md
  • DESIGN-SYSTEM.md
  • INSTALL.md
  • ISSUES.md
  • PLAN.md
  • README.md
  • assets/sounds/pomodoro_chime.opus
  • package.json
  • scripts/check-contrast.ts
  • src-tauri/Cargo.toml
  • src-tauri/capabilities/default.json
  • src-tauri/src/commands/friends.rs
  • src-tauri/src/commands/identity.rs
  • src-tauri/src/commands/models.rs
  • src-tauri/src/commands/sessions.rs
  • src-tauri/src/commands/system.rs
  • src-tauri/src/db/audit_events.rs
  • src-tauri/src/db/migrations.rs
  • src-tauri/src/db/mod.rs
  • src-tauri/src/db/sessions.rs
  • src-tauri/src/lib.rs
  • src-tauri/tauri.conf.json
  • src/App.tsx
  • src/components/AudioOutputPicker.tsx
  • src/components/FocusIndicator.tsx
  • src/components/PairQrCode.tsx
  • src/components/RelayDiagnostics.tsx
  • src/components/ScoreGauge.tsx
  • src/components/SessionTimer.tsx
  • src/components/VideoTile.tsx
  • src/components/WaitingTile.tsx
  • src/design/tokens.ts
  • src/features/ai/ModelPicker.tsx
  • src/features/ai/ModelPickerContainer.tsx
  • src/features/ai/aiAgent.ts
  • src/features/ai/benchmark.ts
  • src/features/ai/focusRequest.ts
  • src/features/ai/focusStore.ts
  • src/features/ai/index.ts
  • src/features/ai/modelStore.ts
  • src/features/ai/parseJudgment.ts
  • src/features/ai/sampleLoop.ts
  • src/features/ai/scoreMachine.ts
  • src/features/friends/AddFriendDialog.tsx
  • src/features/friends/AddFriendDialogView.tsx
  • src/features/friends/FriendsListView.tsx
  • src/features/friends/InboxBoot.tsx
  • src/features/friends/PairDeepLinkBoot.tsx
  • src/features/friends/friendOnlineNotify.ts
  • src/features/friends/inbox.ts
  • src/features/friends/index.ts
  • src/features/friends/invite.ts
  • src/features/friends/inviteRetry.ts
  • src/features/friends/pair.ts
  • src/features/friends/pairDeepLink.ts
  • src/features/friends/pairLink.ts
  • src/features/friends/presence.ts
  • src/features/identity/IdentityLoadError.tsx
  • src/features/identity/IdentityLoadErrorView.tsx
  • src/features/identity/IdentitySetup.tsx
  • src/features/identity/Recover.tsx
  • src/features/identity/RecoverView.tsx
  • src/features/identity/index.ts
  • src/features/identity/recoverLogic.ts
  • src/features/onboarding/AddFriendStep.tsx
  • src/features/onboarding/AddFriendStepView.tsx
  • src/features/onboarding/DisplayNameStep.tsx
  • src/features/onboarding/IdentityChoiceStep.tsx
  • src/features/onboarding/IdentityStep.tsx
  • src/features/onboarding/Onboarding.tsx
  • src/features/onboarding/PermissionsStep.tsx
  • src/features/onboarding/PermissionsStepView.tsx
  • src/features/onboarding/TutorialStep.tsx
  • src/features/session/Report.tsx
  • src/features/session/SessionView.tsx
  • src/features/session/audioDevices.ts
  • src/features/session/host.ts
  • src/features/session/join.ts
  • src/features/session/lifecycle.ts
  • src/features/session/pomodoro.ts
  • src/features/session/pomodoroNotify.ts
  • src/features/session/pomodoroSound.ts
  • src/features/session/reportSerialize.ts
  • src/features/settings/Settings.tsx
  • src/features/settings/categories/AboutCategory.tsx
  • src/features/settings/categories/AdvancedCategory.tsx
  • src/features/settings/categories/AiCategory.tsx
  • src/features/settings/categories/IdentityCategory.tsx
  • src/features/settings/categories/NetworkCategory.tsx
  • src/features/settings/categories/NotificationsCategory.tsx
  • src/features/settings/categories/SessionsCategory.tsx
  • src/features/stats/Dashboard.tsx
  • src/features/stats/FocusInsights.tsx
  • src/features/stats/index.ts
  • src/features/stats/statsData.ts
  • src/features/stats/statsInsights.ts
  • src/features/system/PomodoroNotifyListener.tsx
  • src/features/system/PttListener.tsx
  • src/features/system/QuitConfirmListener.tsx
  • src/features/system/index.ts
  • src/lib/db/audit.ts
  • src/lib/db/identity.ts
  • src/lib/db/sessions.ts
  • src/lib/fileExport.ts
  • src/lib/pomodoro-types.ts
  • src/lib/relayDiagnostics.ts
  • src/lib/trystero/ice.ts
  • src/lib/trystero/index.ts
  • src/lib/trystero/relays.ts
  • src/lib/version.ts
  • src/routes/Home.tsx
  • src/stores/auditStore.ts
  • src/stores/identityStore.ts
  • src/stores/pomodoroStore.ts
  • src/stores/pttStore.ts
  • src/stores/settingsStore.ts
  • src/stories/AddFriendDialog.stories.tsx
  • src/stories/AudioOutputPicker.stories.tsx
  • src/stories/Dashboard.stories.tsx
  • src/stories/FocusInsights.stories.tsx
  • src/stories/IdentityChoiceStep.stories.tsx
  • src/stories/IdentityLoadError.stories.tsx
  • src/stories/ModelPicker.stories.tsx
  • src/stories/Onboarding.stories.tsx
  • src/stories/Recover.stories.tsx
  • src/stories/RelayDiagnostics.stories.tsx
  • src/stories/Report.stories.tsx
  • src/stories/SessionTimer.stories.tsx
  • src/stories/SettingsCategories.stories.tsx
  • src/stories/VideoTile.stories.tsx
  • src/stories/WaitingTile.stories.tsx
  • src/strings.ts
  • tests/ai-eval/RESULTS.md
  • tests/ai-eval/run.ts
  • tests/integration/invite.test.ts
  • tests/integration/pair.test.ts
  • tests/integration/pomodoro.test.ts
  • tests/integration/session.test.ts
  • tests/unit/ai-benchmark.test.ts
  • tests/unit/ai-focus-store.test.ts
  • tests/unit/ai-models.test.ts
  • tests/unit/ai-parse.test.ts
  • tests/unit/ai-sample-loop.test.ts
  • tests/unit/ai-score-machine.test.ts
  • tests/unit/file-export.test.ts
  • tests/unit/ice.test.ts
  • tests/unit/inviteRetry.test.ts
  • tests/unit/pomodoro-custom-bounds.test.ts
  • tests/unit/pomodoro-notify.test.ts
  • tests/unit/pomodoro-wire-compat.test.ts
  • tests/unit/presence.test.ts
  • tests/unit/ptt-store.test.ts
  • tests/unit/recoverLogic.test.ts
  • tests/unit/relay-diagnostics.test.ts
  • tests/unit/report-data.test.ts
  • tests/unit/report-serialize.test.ts
  • tests/unit/session-connection-state.test.ts
  • tests/unit/session-grace.test.ts
  • tests/unit/settings-migration.test.ts
  • tests/unit/settings-network.test.ts
  • tests/unit/stats-data.test.ts
  • tests/unit/stats-insights.test.ts
  • tests/unit/trystero-wrapper.test.ts
  • tests/unit/v2p9-ai-toggle.test.ts
  • tests/unit/version.test.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/improvements-backlog

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is a broad “backlog catch-up” that touches the desktop (Tauri) runtime, networking/presence flows, AI sampling + scoring, session robustness, stats/reporting/export, and corresponding unit/integration tests and Storybook coverage.

Changes:

  • Adds friend-finding and session reliability improvements (relay diagnostics, relay/TURN settings, invite retry, presence goodbye, connection-state UX, PTT failsafes, quit confirmation, deep-link pairing).
  • Refactors and hardens AI request/parsing/scoring behavior (shared focus request builder, “uncertain” parse fallback, confidence floor, download resume bookkeeping).
  • Expands stats/reporting/export and identity safety flows (no-score sessions, report serialize order, CSV/text export helpers, identity load error + safer recovery/overwrite semantics).

Reviewed changes

Copilot reviewed 168 out of 171 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/version.test.ts Unit coverage for semver-ish version comparison used by opt-in update check.
tests/unit/v2p9-ai-toggle.test.ts Verifies off-task confidence floor persistence in settings store.
tests/unit/trystero-wrapper.test.ts Tests joinTopic callback forwarding + relay socket map exposure.
tests/unit/stats-data.test.ts Renames “focused minutes” helpers to “study minutes” and updates tests.
tests/unit/settings-network.test.ts Adds relay/TURN URL validation + parsing tests.
tests/unit/settings-migration.test.ts Adds migration/hydration tests for off-task confidence floor defaults/round-trip.
tests/unit/session-connection-state.test.ts Pins mapping from RTCPeerConnection states to tile focus states.
tests/unit/report-serialize.test.ts Tests report serializer section ordering + score/no-score lines.
tests/unit/report-data.test.ts Aligns audit event record field names to snake_case session_id.
tests/unit/relay-diagnostics.test.ts Tests relay readyState mapping + unreachable detection.
tests/unit/recoverLogic.test.ts Tests overwrite-decision logic based on mnemonic fingerprint matching.
tests/unit/ptt-store.test.ts Tests PTT reset + max-hold failsafe via injectable scheduler.
tests/unit/presence.test.ts Tests presence goodbye behavior for immediate offline transitions.
tests/unit/pomodoro-notify.test.ts Unit tests for local pomodoro boundary detection + notification/chime gating.
tests/unit/pomodoro-custom-bounds.test.ts Tests custom pomodoro duration clamping bounds.
tests/unit/ice.test.ts Adds tests for mapping user TURN server config to ICE options.
tests/unit/ai-parse.test.ts Updates parse fallback expectations to “uncertain” verdict behavior.
tests/unit/ai-models.test.ts Tests interrupted-download recording/clearing behavior in model store.
tests/unit/ai-benchmark.test.ts Updates benchmark fixture/runtime to match new shared focus request shape.
tests/integration/session.test.ts Updates integration expectations for disconnect grace + AI-off score persistence.
tests/integration/pomodoro.test.ts Updates pomodoro start API + adds custom-duration handover test.
tests/integration/pair.test.ts Adds post-arrival stall detection test for pairing flow.
tests/integration/invite.test.ts Adds relay-unreachable vs friend-offline error distinction coverage.
tests/ai-eval/RESULTS.md Documents “uncertain” column semantics in eval confusion matrix.
src/stories/WaitingTile.stories.tsx Storybook stories for new waiting tile variants and layouts.
src/stories/VideoTile.stories.tsx Adds stories for connecting/failed/camera-off/volume states.
src/stories/SettingsCategories.stories.tsx Updates IdentityCategory story signature to include restore callback.
src/stories/SessionTimer.stories.tsx Adds custom pomodoro story and updates interactive start API.
src/stories/Report.stories.tsx Aligns audit event record keys + no-AI baseline score null behavior.
src/stories/RelayDiagnostics.stories.tsx Stories for relay diagnostics panel states.
src/stories/Recover.stories.tsx Adds story for “different identity” overwrite confirmation.
src/stories/Onboarding.stories.tsx Wires back navigation into onboarding step stories.
src/stories/ModelPicker.stories.tsx Adds story for resumable/interrupted model download state.
src/stories/IdentityLoadError.stories.tsx Storybook coverage for identity load error screen.
src/stories/IdentityChoiceStep.stories.tsx Adds “WithBack” story for identity choice step.
src/stories/FocusInsights.stories.tsx Storybook coverage for focus insights view with synthetic data.
src/stories/Dashboard.stories.tsx Updates dashboard stories to include focus insights data.
src/stories/AudioOutputPicker.stories.tsx Storybook story for audio output picker.
src/stories/AddFriendDialog.stories.tsx Adds network-trouble/link-stalled phase stories for pairing UI.
src/stores/pttStore.ts Adds reset() + max-hold failsafe with injectable scheduler seams.
src/stores/pomodoroStore.ts Extends snapshot shape to include explicit work/rest durations.
src/stores/identityStore.ts Adds error identity status + overwrite-safe commit path.
src/stores/auditStore.ts Aligns audit event insert payload to snake_case session_id record.
src/lib/version.ts Adds minimal version parsing/comparison helper for opt-in update check.
src/lib/trystero/relays.ts Adds user-configurable relay override resolver from settings store.
src/lib/trystero/index.ts Adds relay socket map accessor + join error handler forwarding.
src/lib/trystero/ice.ts Incorporates user TURN server into ICE option building.
src/lib/relayDiagnostics.ts Adds pure helpers for relay status snapshotting and reachability checks.
src/lib/pomodoro-types.ts Adds custom preset + bounds clamping + enriched snapshot/start args types.
src/lib/fileExport.ts Adds save-text-file orchestration + slug/date/CSV helpers.
src/lib/db/sessions.ts Adds session delete + clear-all DB commands.
src/lib/db/identity.ts Extends identity key save API to require explicit overwrite flag.
src/lib/db/audit.ts Aligns AuditEventRecord keys + adds list-all audit events API.
src/features/system/QuitConfirmListener.tsx Adds quit-confirm dialog flow triggered by Rust event while in session.
src/features/system/PttListener.tsx Documents no blur-release; relies on store failsafe + per-session reset.
src/features/system/PomodoroNotifyListener.tsx Adds app-wide local pomodoro transition observer.
src/features/system/index.ts Exports new system listeners.
src/features/stats/statsData.ts Renames study-minutes helpers + adds stats CSV model builder.
src/features/stats/index.ts Re-exports insights + CSV model + renamed study-minutes helpers.
src/features/settings/Settings.tsx Adds “restore identity” full-screen flow and wires callback into IdentityCategory.
src/features/settings/categories/NotificationsCategory.tsx Adds toggles for pomodoro + friend-online notification settings.
src/features/settings/categories/AiCategory.tsx Adds off-task confidence floor slider with UI min clamp.
src/features/settings/categories/AboutCategory.tsx Adds opt-in version check toggle + “update available” row.
src/features/session/pomodoroSound.ts Adds local chime sound runtime (injectable for tests).
src/features/session/pomodoroNotify.ts Adds transition detection + side-effect handler for notifications/chime.
src/features/session/join.ts Resets PTT store at session join for privacy/safety.
src/features/session/host.ts Resets PTT store at session host start for privacy/safety.
src/features/session/audioDevices.ts Adds audio output enumeration + setSinkId feature detection.
src/features/onboarding/TutorialStep.tsx Adds optional back navigation secondary action.
src/features/onboarding/PermissionsStepView.tsx Adds optional back navigation secondary action.
src/features/onboarding/PermissionsStep.tsx Threads back navigation through permissions step container.
src/features/onboarding/Onboarding.tsx Implements back navigation with guard rails for identity “point of no return”.
src/features/onboarding/IdentityStep.tsx Threads back action into identity choice and fingerprints into recovery.
src/features/onboarding/IdentityChoiceStep.tsx Adds optional back navigation secondary action.
src/features/onboarding/DisplayNameStep.tsx Adds optional back navigation secondary action.
src/features/onboarding/AddFriendStepView.tsx Adds optional back navigation secondary action.
src/features/onboarding/AddFriendStep.tsx Threads back action into add-friend onboarding step.
src/features/identity/RecoverView.tsx Adds differentiated confirm copy + same-identity done copy support.
src/features/identity/recoverLogic.ts Adds overwrite-decision logic based on mnemonic fingerprint comparison.
src/features/identity/Recover.tsx Wires overwrite-decision into recovery state machine.
src/features/identity/index.ts Exports new identity load error components.
src/features/identity/IdentitySetup.tsx Adds special-case toast for “keys already exist” marker.
src/features/identity/IdentityLoadErrorView.tsx Adds presentational identity load error screen.
src/features/identity/IdentityLoadError.tsx Adds container for identity load error with retry/recover modes.
src/features/friends/pairLink.ts Updates docs to reflect OS deep-link support.
src/features/friends/PairDeepLinkBoot.tsx Adds boot-time subscriber mount for pairing deep links.
src/features/friends/pairDeepLink.ts Implements deep-link subscription + one-time launch URL consumption.
src/features/friends/pair.ts Adds relay override usage + join error forwarding + post-arrival stall hint.
src/features/friends/invite.ts Adds relay-unreachable error type + retry manager + relay override usage.
src/features/friends/index.ts Re-exports deep-link boot + retry manager APIs.
src/features/friends/InboxBoot.tsx Adds presence transition detection for invite retry + friend-online notifications + pagehide goodbye + retry cancel on session end.
src/features/friends/inbox.ts Adds relay override usage + guards joinTopic throw to avoid boot blanking.
src/features/friends/FriendsListView.tsx Improves empty-state CTA and makes Invite button discoverable/accessible.
src/features/friends/friendOnlineNotify.ts Adds opt-in OS notification helper for friend-online edges.
src/features/ai/parseJudgment.ts Changes parse fallback to “uncertain” verdict and adds narrowing helper.
src/features/ai/modelStore.ts Adds interrupted-download tracking APIs and persistence semantics.
src/features/ai/ModelPickerContainer.tsx Records last byte count to persist resumable download offsets on failure/cancel.
src/features/ai/ModelPicker.tsx Surfaces “Resume download” UI based on interrupted-download marker.
src/features/ai/index.ts Re-exports new focus request builder + uncertain verdict types + backoff exports.
src/features/ai/focusRequest.ts Introduces single source of truth for focus chat request body shape.
src/features/ai/aiAgent.ts Updates docs to reference new focus request builder terminology.
src/design/tokens.ts Adds shared score gauge sizing token.
src/components/WaitingTile.tsx Adds new calm waiting tile component.
src/components/ScoreGauge.tsx Switches default size to design token.
src/components/RelayDiagnostics.tsx Adds relay diagnostics panel component with polling and controlled seam.
src/components/PairQrCode.tsx Improves QR size/EC level for scan reliability.
src/components/FocusIndicator.tsx Adds connection focus states (connecting/failed) with glyphs + labels.
src/components/AudioOutputPicker.tsx Adds audio output device picker component (feature-detected).
src/App.tsx Mounts new system listeners (quit confirm + pomodoro notify).
src-tauri/tauri.conf.json Enables deep-link plugin and macOS signing config.
src-tauri/src/db/sessions.rs Adds delete/clear_all with audit event cleanup, plus tests.
src-tauri/src/db/migrations.rs Adds explicit “newer schema” refusal error type and tests.
src-tauri/src/db/audit_events.rs Adds list_all query and tests; documents serde naming contract.
src-tauri/src/commands/sessions.rs Exposes sessions delete/clear + audit events list_all commands.
src-tauri/src/commands/identity.rs Adds overwrite guard + stable error marker + signing key loader helper.
src-tauri/Cargo.toml Adds deep-link/dialog/single-instance plugins; adjusts crypto_box features.
src-tauri/capabilities/default.json Grants dialog + deep-link plugin capabilities.
README.md Updates network disclosures and macOS release matrix notes.
package.json Adds @tauri-apps/plugin-deep-link and @tauri-apps/plugin-dialog deps.
package-lock.json Locks new Tauri plugin dependencies.
INSTALL.md Updates macOS install guidance for Apple Silicon-only + ad-hoc signing.
DESIGN-SYSTEM.md Updates component catalog entries and some UI behavior docs.
.github/workflows/release.yml Updates release body copy regarding signing status.
.github/workflows/release-prep.yml Adds pre-tag quality gate job and wires prep behind it.
.github/workflows/ci.yml Adds check-strings enforcement in CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/version.ts
Comment on lines +14 to +18
for (let i = 0; i < parts.length; i++) {
const n = Number(parts[i])
if (!Number.isInteger(n) || n < 0) return null
out[i] = n
}
Comment on lines +105 to 109
if (decision === 'commit') {
setSameIdentity(identityExists)
void commit()
return
}
Comment on lines 128 to 132
onCancelOverwrite={() => {
pendingCommit.current = null
setConfirmDifferent(false)
setPhase('input')
}}
@scotej
scotej merged commit 82f1a11 into main Jun 12, 2026
1 check passed
@scotej
scotej deleted the feat/improvements-backlog branch June 12, 2026 23:27
Copilot stopped work on behalf of scotej due to an error June 12, 2026 23:27
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.

3 participants