Repository navigation
Conversation
- Replace duplicate Simpson's paradox (#4) with sunk cost fallacy trap - Remove answer-revealing constraints from #0, #1, #2 (model must derive insights) - Rebalance dominated options in #13 (cloud costs) and #14 (prioritization) - Add ethical dimension to #6 (government censorship client) - Add data ambiguity to #10 (contested Phase 1 biomarker subgroup)
- Add elapsed timer, round progress (models done/total), discovery turn counter, per-model costs, and tool-use indicators to the web UI - Fix CostTracker pricing: add ModelIDLookup so TotalCost() resolves short keys (e.g. "gpt") to model IDs for correct pricing lookups - Wire configPricingAdapter in all entrypoints (web, TUI, eval runner) - Add StreamType to stream events to distinguish content vs tool calls - Regenerate golden snapshots to reflect corrected cost values
The web handler dispatches actions in goroutines that mutate State (Activities, LogLines, SessionDir) while the event loop concurrently reads those fields. Add an RWMutex to State with locking in the write methods (Log, AddActivity, AddModelActivity, AddSystemActivity, SetError) and in ExecutePersist, updateActivityExcerpt, and sendState. Also log a warning (once per model) when PricingProvider falls back to default $2/$10 pricing for an unknown model ID.
forwardStreamEvents runs as a detached goroutine that sends to the caller's eventCh. After close(internalCh), buffered items may still be draining to eventCh. If the caller returns and ws.go closes eventCh, the forwarder panics with "send on closed channel". Wait for the forwarder to finish via a done channel before returning from CallWithToolsStreaming and CallDiscoveryStreaming.
Replace conditional rendering in App.tsx with wouter routes (/, /debate, /sessions, /sessions/:id). LandingScreen now uses navigate() instead of callback props. Add SPA-aware static file handler that falls back to index.html for unmatched paths in prod mode.
- Fix loadFromSessionData using hardcoded 6-model count for all rounds; round 4 (synthesis) has only 2 models, causing incorrect resume detection. Now uses preset-aware per-round speaking order. - Remove dead code: ResumableSessionWriter, duplicate SessionLoader interface, orphaned WriteDiscovery method, hand-rolled joinStrings (use strings.Join). - Fix WriteKnowledgeBase silently swallowing JSON unmarshal errors. - Fix Writer.Data() returning raw pointer under mutex; now returns value copy. - Add TestLoadState_NonUniformRounds covering the resume bug.
…ements Session persistence: single session.json format with slug-based IDs, updated debate runner, TUI model, web handlers, and frontend pages. Eval framework: add LLM judge, baseline comparison, parallel execution, voting system; remove old extract/curate scripts. Web UI: add client components (ask-user overlay, completion summary, shared Badge/GlowDot/Panel), Vite config, SPA routing, dashboard updates. Infrastructure: cassette recorder enhancements, openrouter cache layer, sim fault improvements, golden snapshot updates.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR comprehensively redesigns the system from a multi-round debate framework to a single-room collaborative chat model, introduces web and Electron UI support, restructures the evaluation framework from War Room to Decision scenarios, and refactors session and prompt infrastructure to support transcript-first state management. Changes
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
Add native Electron desktop app that communicates with the Go backend via JSON-RPC 2.0 over stdin/stdout, replacing the need for HTTP/WS. Go side: - New `internal/jsonrpc/` package: protocol types, stdio server, session management with proper goroutine lifecycle and race-free design - New `warroom stdio` subcommand for Electron IPC - Export SnapshotFromState, DispatchAction, TruncateExcerpt, SessionsBasePath from internal/web/ for shared use Electron side: - Forge + Vite build with React 19 renderer - go-bridge.ts spawns Go binary, manages JSON-RPC over stdio - Full React UI migrated from web/src/ with IPC-based useDebate hook - Auto-updates via electron-updater, system tray, native menu - Window state persistence, macOS/Windows platform support Build pipeline: - Justfile recipes for dev, cross-compile, package, and publish - GitHub Actions workflow for cross-platform release builds
Replaced all 5 trap scenarios with domain-specific traps (network effects misidentification, cloud TCO bias, pharma evergreening, hub-and-spoke economics, AV safety statistics). Added LEARNINGS.md documenting why traps are still too easy and research into harder eval approaches (key insights checklists, adversarial filtering, external knowledge gates).
Break up monolithic components and extract reusable primitives: - Move shared/ to ui/, add Collapsible, ErrorBanner, LoadingState, StatusBadge - Extract PageShell layout (dot-grid, noise, titlebar padding) - Split AskUserOverlay into QuestionStep + formatAnswers - Split DebateDashboard into IntelFeed + InterviewPlaceholder - Extract useNotifications and useSessions hooks from useDebate/pages - CompletionSummary and IntelFeed now use Collapsible - Session pages use PageShell, StatusBadge, useSessions
- Replace Vite configs with Webpack for Electron main/renderer processes - Switch to pnpm workspace for Electron dependency management - Refactor preset prompts and system prompts for single-room chat model - Update SessionDetailPage UI in both web and Electron renderers - Simplify TUI layout and view (remove unused rendering code) - Clean up docs and README
Closes multiple Electron UI gaps vs backend capabilities: Backend (Go): - Wire sessionId param through JSON-RPC initialize for session resume - Pass ResumeSession to pipeline builder so LoadSessionStep runs Frontend: - Settings UI: preset selector, cheap mode toggle, API key warning, multiline topic input on landing screen - Session resume: RESUME button on session list/detail pages, passes sessionId through to Go initialize - Shutdown/cancel: CANCEL button in header calls shutdown RPC, navigates home - Error recovery: ErrorBanner now has DISMISS and GO HOME actions - Transcript export: EXPORT MD button copies markdown to clipboard (with download fallback), available during debate and on session detail - Transcript rendering: markdown headings/bold/italic/code, visual differentiation for tool events (dimmer, mono) and vote events (accent border) - Per-model cost: ModelCard shows individual model cost, ModelRoster passes modelCosts from snapshot - Voting UX: progress bar in roster footer, per-agent confidence bar with ballot text, VOTED badge, sorted ballots in CompletionSummary with confidence bars and reasoning https://claude.ai/code/session_01QPxpz4R7j4MFwGAqLEkwpb
- Fix data corruption risk: replace effectiveTopic=sessionID hack with a bool hasTopic parameter on eventLoop, so a failed resume never leaves a session ID in the topic field - Fix path traversal: validate sessionId in initialize handler using the same check as getSession (reject /, \, .., .) - Fix silent failure: config fetch error now sets configError state and defaults hasAPIKey to false (fail-safe), shows backend connection error banner - Extract shared lib/export.ts with transcriptToMarkdown and copyOrDownload — removes duplicate code from DebateDashboard and SessionDetailPage - Extract shared BallotCard component from CompletionSummary into ui/BallotCard.tsx, reused by SessionDetailPage - Fix shutdown not resetting state: shutdown callback now resets to INITIAL_STATE after cleanup - Fix setTimeout memory leak: export flash timers now use refs with cleanup on unmount - Consolidate TranscriptEvent types: useSessions.ts now imports from types/protocol.ts instead of defining its own incomplete copy - Fix inconsistent styling: text-red-400 → text-error in session pages https://claude.ai/code/session_01QPxpz4R7j4MFwGAqLEkwpb
Core resilience: - #1: Add React ErrorBoundary wrapping the app — render errors now show a styled fallback with reload button instead of a white screen - #2: Wire onUpdateDownloaded from preload into useDebate state so the renderer can display an update-available banner - #4: Remove dead submitTopic from useDebate hook and DebatePage - #5: Add backend crash detection — main process forwards Go exit event via IPC, preload exposes onBackendExited, useDebate sets connected=false and shows error banner when backend dies - #8: Fix route param changes being silently ignored — remove stale connectedRef guard; useEffect now disconnects previous session and reconnects on topic/resume change - #11: Fix O(n²) activity scan per stream tick — walk backwards and break on first match instead of .map + .slice().some() per element - #19: Add beforeunload handler during active debates to prevent accidental window close / data loss Accessibility: - #6: Add ARIA attributes across all components — role="alert" on ErrorBanner, role="status" + aria-label on GlowDot, role="complementary" on ModelRoster, role="progressbar" on progress bars, aria-label on textarea and dialog, aria-checked on QuestionStep options - #12: Add focus management to AskUserOverlay — saves previous focus, auto-focuses first interactive element on mount, restores focus on unmount, implements keyboard focus trap (Tab/Shift+Tab) - #14: Surface JSON parse errors in AskUserOverlay — shows visible error state with dismiss button instead of silently fabricating a question - #15: Fix partial answer submission — check raw answers array for all-empty instead of checking formatted string against "(no answer)" UX polish: - #3: Delete dead LoadingState component (zero imports) - #7: Lower noise-overlay z-index from 50 to 1 to avoid stacking conflict with titlebar drag region - #9: Add "Open Folder" button to SessionListPage using the existing but previously unused openSessionsFolder preload API - #10: Extract renderTranscriptEvent and roleBadge as pure functions outside DebateDashboard component to avoid recreation on every render - #13: Replace hardcoded Tailwind colors in StatusBadge with theme tokens (text-success, text-error, text-warning) - #16: Add window.confirm() before shutdown to prevent accidental cancellation of in-progress debates - #18: Add refresh() to useSessionList hook, wire refresh button and visibilitychange auto-refresh to SessionListPage - #21: Remove defaultOpen from transcript Collapsibles in SessionDetailPage — long transcripts now load collapsed https://claude.ai/code/session_01QPxpz4R7j4MFwGAqLEkwpb
Display the 5 most recent sessions inline on the home screen so users can resume in-progress sessions or reuse a previous topic without navigating to the full sessions page. - RESUME button on in-progress sessions navigates to debate with resume - REUSE button on completed sessions copies the topic into the textarea - Page switches from vertically-centered to top-aligned when sessions exist - Clean first-run experience: section hidden when no sessions exist https://claude.ai/code/session_01QPxpz4R7j4MFwGAqLEkwpb
Add async-loaded session list below topic input. Tab toggles focus between text input and session list. In-progress sessions can be resumed; completed sessions have their topic reused.
Both call sites in pipeline.go used the deprecated config.HasNativeSearch wrapper. Replace with an inline adapter that calls the canonical HasNativeSearchByID, satisfying staticcheck SA1019.
- Change AgentSet.HasNativeSearch field from func(string) bool to func(string) (bool, error) so config.HasNativeSearchByID can be assigned directly without a wrapper - Update IsNativeSearch to handle errors explicitly (unknown model → false) - Wire config.HasNativeSearchByID directly in both pipeline.go call sites - Remove the deprecated config.HasNativeSearch shim; it no longer has callers - Migrate TestHasNativeSearch → TestHasNativeSearchByID, testing error cases for unknown model IDs rather than silently returning false
Summary
session.jsonper session with slug-based IDs (k7m2x9pa-should-we-adopt-rust) replacing timestamp dirs with 10+ scattered files. Preset-aware resume detection, thread-safe writer, legacy read fallbackTest plan
go test ./...— all packages passgolangci-lint run ./...— 0 issuesnpx tsc --noEmit— TypeScript cleango run ./cmd/evalruns end-to-endSummary by CodeRabbit
New Features
Chores