Skip to content

Conversation

@NomadicDaddy
Copy link

@NomadicDaddy NomadicDaddy commented Dec 23, 2025

Double-Check Mode

Adds an optional verification step where a second AI agent reviews completed features before they're approved. Useful for non-test driven modes or you just don't trust one model's take...

Features

Configurable in Settings - Enable/disable double-check mode with model selection options:

  • Different Model: Use a different model than the one that implemented the feature
  • Specific Model: Always use a specific model (Opus, Sonnet, or Haiku)
  • Same Model: Use the same model that implemented the feature

New "Double-Check" column on the board - Features pending verification appear here

Auto Mode Integration:

  • Toggle to auto-trigger double-check when auto mode is running
  • Double-check features are prioritized over new backlog items
  • Failed double-check sends feature back to backlog for re-implementation
  • In-progress features with saved context are auto-resumed

Flow

  1. Feature completes implementation → moves to double_check status
  2. Verification agent reviews the implementation
  3. If passed → moves to waiting_approval
  4. If failed → returns to backlog with feedback for re-implementation

Changes

  • New settings UI section for Double-Check Mode configuration
  • Server-side double-check verification logic in auto-mode-service
  • Deep merge for doubleCheckMode settings persistence
  • Auto-mode now handles: double-check → in-progress resume → backlog (in priority order)
{EED2DA43-05E8-4ABE-B98B-914D3DFF36F4} {98F92E4B-B424-4BC4-A243-7910BFBC45D8} {4D2A4E63-A4B6-4619-8984-B2782397017B} {DBBB1169-793A-43D8-A08D-0B79CB0A76B0}

Summary by CodeRabbit

Release Notes

  • New Features

    • Added double-check verification workflow to validate features before approval with configurable verification model strategy
    • Added double-check column to board view with "Run Double-Check" and "Skip" action buttons
    • Added double-check settings panel with model strategy selection (specific/different/any) and auto-trigger in auto mode option
  • Style

    • Added double-check status color theme across all application themes

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 23, 2025

Walkthrough

This PR implements a double-check verification feature for the auto-mode workflow, including backend service updates to integrate SettingsService, new API endpoints for double-check operations, frontend UI for settings and board interactions, type definitions for double-check configurations, and styling updates across all themes.

Changes

Cohort / File(s) Summary
Backend Service Foundation
apps/server/src/index.ts, apps/server/src/services/auto-mode-service.ts, apps/server/src/services/settings-service.ts
AutoModeService constructor updated to accept optional SettingsService; double-check verification workflow added including model selection, prompt building, result persistence, and status transitions; settings service integrated for loading global/double-check configuration; deep-merge logic added for doubleCheckMode in SettingsService
API Routes & Endpoints
apps/server/src/routes/auto-mode/index.ts, apps/server/src/routes/auto-mode/routes/double-check-feature.ts, apps/server/src/routes/agent/routes/model.ts
New POST /double-check-feature route added with handler; model.ts endpoint description updated and behavior changed from persisting model changes to acknowledgment response (parameter renamed to _agentService)
Server Tests
apps/server/tests/unit/services/auto-mode-service-double-check.test.ts
Comprehensive test suite for double-check functionality covering determineFinalStatus, model selection strategies, prompt building, and title extraction
Type Definitions
libs/types/src/settings.ts, libs/types/src/feature.ts, libs/types/src/event.ts, libs/types/src/index.ts, apps/server/src/types/settings.ts
DoubleCheckMode, DoubleCheckModelStrategy, and DoubleCheckResult types introduced; Feature type extended with doubleCheckResult field; FeatureStatus union includes 'double_check'; GlobalSettings augmented with doubleCheckMode
Frontend Store & Persistence
apps/ui/src/store/app-store.ts, apps/ui/src/lib/electron.ts, apps/ui/src/lib/http-api-client.ts, apps/ui/src/types/electron.d.ts, apps/ui/src/hooks/use-settings-migration.ts
AppState extended with doubleCheckMode; Feature.status includes 'double_check'; new AutoModeAPI method doubleCheckFeature added; settings migration includes doubleCheckMode payload
Settings UI
apps/ui/src/components/views/settings-view.tsx, apps/ui/src/components/views/settings-view/config/navigation.ts, apps/ui/src/components/views/settings-view/double-check/*
New DoubleCheckSection component for toggling verification, selecting model strategy, and configuring auto-trigger behavior; settings view navigation extended with 'double-check' entry
Board View & Actions
apps/ui/src/components/views/board-view.tsx, apps/ui/src/components/views/board-view/hooks/use-board-actions.ts, apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts
New handlers handleDoubleCheck and handleSkipDoubleCheck added to board actions; double-check scheduling prioritizes features when enabled; slot accounting tracks double-check usage; feature loading filters by status
Kanban Board Components
apps/ui/src/components/views/board-view/kanban-board.tsx, apps/ui/src/components/views/board-view/components/kanban-card/*, apps/ui/src/components/views/board-view/constants.ts
New 'double_check' column added with conditional visibility based on doubleCheckMode; KanbanCard and CardActions extended with onDoubleCheck/onSkipDoubleCheck callbacks; double-check cards rendered as draggable
Styling & Themes
apps/ui/src/styles/global.css, apps/ui/src/styles/themes/*.css (16 theme files)
--status-double-check CSS variable added to global styles and all theme variants with consistent purple-blue hue (oklch 280°); color tokens vary per theme (lightness 0.52–0.72, saturation 0.12–0.18)

Sequence Diagram(s)

sequenceDiagram
    participant User as User<br/>(Frontend)
    participant UI as Board UI<br/>(React)
    participant API as HTTP/Electron<br/>API Layer
    participant Server as AutoModeService<br/>(Backend)
    participant Settings as SettingsService
    participant Agent as AgentProvider<br/>(AI Model)
    participant Feature as Feature<br/>Storage

    User->>UI: Click "Run Double-Check"<br/>on feature card
    UI->>API: handleDoubleCheck(feature)
    API->>Server: POST /api/auto-mode/double-check-feature<br/>{projectPath, featureId}
    
    Server->>Settings: getGlobalSettings()
    Settings-->>Server: doubleCheckMode config
    
    Server->>Feature: loadFeature(featureId)
    Feature-->>Server: feature data
    
    rect rgb(135, 206, 250, 0.2)
        Note over Server,Agent: Double-Check Verification Phase
        Server->>Server: getDoubleCheckModel(strategy)
        Server->>Server: buildDoubleCheckPrompt(feature)
        Server->>Agent: Execute verification prompt<br/>with selected model
        Agent-->>Server: [DOUBLE_CHECK_PASSED]<br/>or [DOUBLE_CHECK_FAILED]
    end
    
    Server->>Server: determineFinalStatus()<br/>parse results
    Server->>Feature: updateFeatureWithDoubleCheckResult<br/>(passed/failed, summary, discrepancies)
    Feature-->>Server: acknowledged
    
    Server-->>API: {success, passed, summary, discrepancies}
    API-->>UI: results
    
    UI->>UI: Update feature status<br/>display discrepancies
    UI-->>User: Show verification result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

Testers-Requested, Refactor, Tests

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Double-Check Mode' directly and clearly summarizes the main feature addition in the changeset: a new verification workflow where a second AI agent reviews completed features. This is the primary focus of the PR as confirmed by the PR objectives and all major changes across server, UI, and styling components.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @NomadicDaddy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant new feature called 'Double-Check Mode,' designed to improve the quality and reliability of AI-implemented features. It provides an optional, configurable verification step where a secondary AI agent rigorously reviews completed work. This ensures that features meet specified criteria before proceeding to human approval, effectively acting as an automated quality gate. The implementation includes both front-end UI changes for configuration and status visualization, as well as robust back-end logic to manage the verification process and integrate seamlessly with the existing Auto Mode workflow.

Highlights

  • New Double-Check Mode: Introduces an optional verification step where a second AI agent reviews completed features before they are approved, enhancing reliability, especially for non-test-driven development.
  • Configurable Model Selection: Allows users to configure the AI model used for double-checking, with options to use a different model, a specific model (Opus, Sonnet, Haiku), or the same model that implemented the feature.
  • Integrated Auto Mode Workflow: Auto Mode now integrates double-check features, prioritizing them over new backlog items. Failed double-checks send features back to the backlog for re-implementation, and in-progress features with saved context are auto-resumed.
  • New UI and API Endpoints: Adds a new 'Double-Check' column to the board UI, a dedicated settings section for configuration, and new server-side API endpoints and logic to manage the double-check process.
  • Enhanced Feature Status Management: Updates feature status transitions to include 'double_check', ensuring proper flow from implementation to approval, and handles persistence of double-check results and settings.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a significant new feature, "Double-Check Mode," which adds an optional AI-driven verification step for completed features. The implementation is comprehensive, with changes across the server, UI, and shared types. The overall approach is solid, but I've identified a critical bug in the server-side implementation that would prevent the double-check process from being stopped. Additionally, there are opportunities to improve code safety with better request validation and enhance maintainability by refactoring duplicated logic in the UI. I've also noted an unrelated functional change that disables model switching, which should be clarified. Expanding the new unit tests to cover the core doubleCheckFeature method would also be beneficial.

I am having trouble creating individual review comments. Click here to see my feedback.

apps/server/src/services/auto-mode-service.ts (555)

critical

This abortController declaration shadows the one from the outer scope (line 521). The abortController from line 521 is stored in this.runningFeatures, but this new one is passed to executeQuery. This means stopFeature will not work for this operation as it will abort the wrong controller. You should remove this line and use the abortController from the outer scope.

apps/server/src/routes/agent/routes/model.ts (22-23)

high

This change disables the functionality to set the session model. The new implementation is a stub that always returns success. While the comment in the new code indicates this is intentional (// Model changes are not yet implemented), this is a significant functional change that seems unrelated to the Double-Check Mode feature. If this is a temporary measure, it might be better to handle it in a separate PR to avoid confusion. If it's permanent, the endpoint should probably be removed.

apps/server/src/routes/auto-mode/routes/double-check-feature.ts (12-15)

medium

Using a type assertion as { ... } for the request body is not type-safe and can lead to runtime errors if the client sends an unexpected payload. It's better to use a validation library like Zod to parse and validate the request body. This ensures that projectPath and featureId are of the correct type and are present.

apps/server/tests/unit/services/auto-mode-service-double-check.test.ts (1-165)

medium

It's great that you've added unit tests for the new double-check functionality. However, the tests currently cover helper methods but not the main doubleCheckFeature method itself. This method contains the core logic for the feature, including interactions with the provider, file system, and event emitters. Please consider adding tests for doubleCheckFeature to cover its success and failure paths, ensuring the logic is robust.

apps/ui/src/components/views/board-view.tsx (644-662)

medium

The logic for filtering features by the current worktree branch is duplicated here and in other parts of this useEffect (lines 696-716 and 741-763). To improve maintainability and reduce code duplication, consider extracting this filtering logic into a reusable helper function. This would make the effect easier to read and ensure consistency across the different feature types (double-check, in-progress, backlog).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (12)
apps/server/src/routes/agent/routes/model.ts (1)

9-9: Consider removing the unused parameter.

The _agentService parameter is no longer used in the handler. If it's not required for interface compatibility, consider removing it entirely to clarify the intent.

🔎 Proposed refactor
-export function createModelHandler(_agentService: AgentService) {
+export function createModelHandler() {
   return async (req: Request, res: Response): Promise<void> => {

If the parameter must remain for interface compatibility with other route handlers, add a comment explaining why:

+// Parameter kept for compatibility with route handler factory signature
 export function createModelHandler(_agentService: AgentService) {
libs/types/src/feature.ts (1)

8-27: Well-structured type definition for double-check results.

The DoubleCheckResult interface provides a clear schema for verification data. Consider the following for future enhancements:

  1. The checkedAt field is documented as an ISO timestamp but typed as string. Consider using a branded type or adding runtime validation to ensure ISO 8601 format consistency.
  2. The discrepancies array uses plain strings. If more structured error reporting becomes necessary, consider defining a structured discrepancy type.

These are optional improvements and don't block the current implementation.

apps/server/src/routes/auto-mode/routes/double-check-feature.ts (1)

32-35: Error message exposure in production.

The current error handling returns the full error message to the client, which could leak sensitive implementation details in production. Consider using generic error messages for 500 errors.

🔎 Proposed improvement
     } catch (error) {
       logError(error, 'Double-check feature failed');
-      res.status(500).json({ success: false, error: getErrorMessage(error) });
+      const isDevelopment = process.env.NODE_ENV === 'development';
+      res.status(500).json({ 
+        success: false, 
+        error: isDevelopment ? getErrorMessage(error) : 'Internal server error'
+      });
     }
apps/server/tests/unit/services/auto-mode-service-double-check.test.ts (1)

67-148: Prefer exercising double-check behavior via public API instead of private methods

These tests reach into determineFinalStatus, getDoubleCheckModel, buildDoubleCheckPrompt, and extractTitleFromDescription via (service as any), which makes them fragile against internal refactors. If there is (or will be) a public method that drives the double-check flow end-to-end, consider adding at least one higher-level test that asserts the same behavior through that entrypoint, keeping these private-method tests only where necessary.

apps/ui/src/components/views/board-view/kanban-board.tsx (1)

89-103: Tighten store subscription and consider behavior when disabling Double-Check Mode

const { doubleCheckMode } = useAppStore(); subscribes the board to the entire store and will re-render on any state change. You can avoid unnecessary renders by selecting just what you need, e.g.:

Suggested selector usage
const doubleCheckMode = useAppStore((state) => state.doubleCheckMode);

Also note that when doubleCheckMode.enabled is turned off, visibleColumns drops the double_check column entirely. Any existing features in double_check will effectively disappear from the Kanban view until the mode is re-enabled. If that’s not the desired UX, consider either:

  • auto-transitioning such features out of double_check when disabling the mode, or
  • keeping the column visible but visually indicating that double-check is disabled.
apps/ui/src/components/views/settings-view/double-check/double-check-section.tsx (2)

37-48: Use a selector when reading from useAppStore to limit re-renders

const { doubleCheckMode, setDoubleCheckMode } = useAppStore(); will re-render this section on any store change. To keep settings UI snappy, it’s better to subscribe only to what you need, e.g.:

Suggested selector
const { doubleCheckMode, setDoubleCheckMode } = useAppStore((state) => ({
  doubleCheckMode: state.doubleCheckMode,
  setDoubleCheckMode: state.setDoubleCheckMode,
}));

73-97: Settings description should match all model strategies, not just “different model”

The help text under “Enable Double-Check Verification” says “A different model reviews the implementation…”, but users can also choose “Specific Model” or “Same Model”. Consider rephrasing to something strategy-agnostic like “A verification model reviews the implementation…” so the copy stays correct regardless of the selected strategy.

apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx (2)

17-36: Remove or wire up unused onMoveBackToInProgress prop

onMoveBackToInProgress is declared in CardActionsProps and passed down from KanbanCard, but it isn’t used anywhere in this component. Either hook it into an appropriate action (e.g., a “Send back to In Progress” control) or drop the prop to avoid confusion and keep the surface area lean.


293-330: Double-check action buttons are correctly integrated

The new “Run Double-Check” and “Skip” buttons for feature.status === 'double_check' are consistent with the existing action patterns (guarded by handler presence, stop event propagation, and include test IDs). The behavior and styling look coherent with the rest of the card actions.

If you expect double-checks to be long-running, you might optionally disable these buttons or show a busy state while a double-check is in progress to prevent duplicate requests.

apps/ui/src/components/views/board-view/hooks/use-board-actions.ts (2)

494-555: Double-check and skip handlers align well with existing board actions

handleDoubleCheck sensibly guards against missing APIs, surfaces progress via toasts, and reloads features on success so status transitions driven by the server are reflected in the UI. handleSkipDoubleCheck performs a straightforward transition to waiting_approval and persists it.

If you later attach more double-check-specific state (e.g., doubleCheckResult display on cards), consider clearing or updating that alongside the status in handleSkipDoubleCheck to keep the client view fully in sync with whatever the server stores.


808-937: Consider applying concurrency checks to double-checks triggered via handleStartNextFeatures

handleStartNextFeatures now prioritizes double_check features ahead of backlog, which matches the intended flow. However, the new double-check branch runs before availableSlots is computed and the concurrency guard is applied, so pressing “Start Next” can launch a double-check even when runningAutoTasks.length is already at maxConcurrency.

If you want the UI behavior to respect concurrency limits uniformly (including verification work), you could:

  • Compute availableSlots and bail early when <= 0 before entering the double-check branch, and
  • Optionally reuse availableSlots to cap how many double-checks you start, mirroring what you already do later for backlog items.

This would make manual “Start Next” behavior consistent with the auto-mode scheduler’s slot accounting.

apps/server/src/services/auto-mode-service.ts (1)

360-373: Consider differentiating error scenarios in logs.

The method returns null for both missing service and load failures. While the error is logged, callers cannot distinguish between "settings service unavailable" and "settings load failed."

🔎 Optional: Add context to error logs
  private async loadGlobalSettings(): Promise<GlobalSettings | null> {
    if (!this.settingsService) {
+     console.warn('[AutoMode] Settings service not available, double-check mode disabled');
      return null;
    }
    try {
      return await this.settingsService.getGlobalSettings();
    } catch (error) {
-     console.error('[AutoMode] Failed to load global settings:', error);
+     console.error('[AutoMode] Failed to load global settings (double-check may not work):', error);
      return null;
    }
  }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d4d4b8f and 64c8623.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (50)
  • apps/server/src/index.ts
  • apps/server/src/routes/agent/routes/model.ts
  • apps/server/src/routes/auto-mode/index.ts
  • apps/server/src/routes/auto-mode/routes/double-check-feature.ts
  • apps/server/src/services/auto-mode-service.ts
  • apps/server/src/services/settings-service.ts
  • apps/server/src/types/settings.ts
  • apps/server/tests/unit/services/auto-mode-service-double-check.test.ts
  • apps/ui/src/components/views/board-view.tsx
  • apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx
  • apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx
  • apps/ui/src/components/views/board-view/constants.ts
  • apps/ui/src/components/views/board-view/hooks/use-board-actions.ts
  • apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts
  • apps/ui/src/components/views/board-view/kanban-board.tsx
  • apps/ui/src/components/views/settings-view.tsx
  • apps/ui/src/components/views/settings-view/config/navigation.ts
  • apps/ui/src/components/views/settings-view/double-check/double-check-section.tsx
  • apps/ui/src/components/views/settings-view/double-check/index.ts
  • apps/ui/src/components/views/settings-view/hooks/use-settings-view.ts
  • apps/ui/src/hooks/use-settings-migration.ts
  • apps/ui/src/lib/electron.ts
  • apps/ui/src/lib/http-api-client.ts
  • apps/ui/src/store/app-store.ts
  • apps/ui/src/styles/global.css
  • apps/ui/src/styles/themes/blossom.css
  • apps/ui/src/styles/themes/cream.css
  • apps/ui/src/styles/themes/dark.css
  • apps/ui/src/styles/themes/forest.css
  • apps/ui/src/styles/themes/github.css
  • apps/ui/src/styles/themes/gray.css
  • apps/ui/src/styles/themes/gruvboxlight.css
  • apps/ui/src/styles/themes/lavender.css
  • apps/ui/src/styles/themes/mint.css
  • apps/ui/src/styles/themes/nordlight.css
  • apps/ui/src/styles/themes/ocean.css
  • apps/ui/src/styles/themes/paper.css
  • apps/ui/src/styles/themes/peach.css
  • apps/ui/src/styles/themes/rose.css
  • apps/ui/src/styles/themes/sand.css
  • apps/ui/src/styles/themes/sepia.css
  • apps/ui/src/styles/themes/sky.css
  • apps/ui/src/styles/themes/snow.css
  • apps/ui/src/styles/themes/solarizedlight.css
  • apps/ui/src/styles/themes/sunset.css
  • apps/ui/src/types/electron.d.ts
  • libs/types/src/event.ts
  • libs/types/src/feature.ts
  • libs/types/src/index.ts
  • libs/types/src/settings.ts
🧰 Additional context used
🧬 Code graph analysis (12)
apps/ui/src/components/views/settings-view.tsx (2)
apps/ui/src/components/views/settings-view/double-check/double-check-section.tsx (1)
  • DoubleCheckSection (37-253)
apps/ui/src/components/views/settings-view/double-check/index.ts (1)
  • DoubleCheckSection (1-1)
apps/server/tests/unit/services/auto-mode-service-double-check.test.ts (1)
apps/server/src/services/auto-mode-service.ts (1)
  • AutoModeService (337-2934)
apps/server/src/services/settings-service.ts (2)
libs/types/src/index.ts (1)
  • DEFAULT_GLOBAL_SETTINGS (76-76)
libs/types/src/settings.ts (1)
  • DEFAULT_GLOBAL_SETTINGS (454-485)
libs/types/src/feature.ts (4)
libs/types/src/index.ts (3)
  • DoubleCheckResult (24-24)
  • AgentModel (42-42)
  • FeatureStatus (23-23)
apps/server/src/types/settings.ts (1)
  • AgentModel (11-11)
libs/types/src/settings.ts (1)
  • AgentModel (12-12)
libs/types/src/model.ts (1)
  • AgentModel (23-23)
apps/server/src/index.ts (1)
apps/server/src/services/auto-mode-service.ts (1)
  • AutoModeService (337-2934)
apps/ui/src/components/views/settings-view/double-check/double-check-section.tsx (5)
libs/types/src/settings.ts (2)
  • DoubleCheckModelStrategy (80-80)
  • DoubleCheckMode (88-97)
apps/ui/src/components/views/settings-view/double-check/index.ts (1)
  • DoubleCheckSection (1-1)
apps/ui/src/store/app-store.ts (1)
  • useAppStore (967-2735)
apps/ui/src/hooks/use-settings-migration.ts (1)
  • syncSettingsToServer (195-241)
apps/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/server/src/routes/auto-mode/index.ts (2)
apps/server/src/middleware/validate-paths.ts (1)
  • validatePathParams (22-69)
apps/server/src/routes/auto-mode/routes/double-check-feature.ts (1)
  • createDoubleCheckFeatureHandler (9-37)
apps/ui/src/store/app-store.ts (3)
apps/server/src/types/settings.ts (1)
  • DoubleCheckMode (16-16)
libs/types/src/index.ts (1)
  • DoubleCheckMode (62-62)
libs/types/src/settings.ts (1)
  • DoubleCheckMode (88-97)
apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx (1)
apps/ui/src/components/ui/button.tsx (1)
  • Button (108-108)
apps/ui/src/components/views/board-view.tsx (1)
apps/ui/src/store/app-store.ts (1)
  • useAppStore (967-2735)
apps/ui/src/components/views/board-view/hooks/use-board-actions.ts (4)
apps/ui/src/store/app-store.ts (1)
  • Feature (257-279)
libs/types/src/feature.ts (1)
  • Feature (46-81)
apps/ui/src/lib/electron.ts (1)
  • getElectronAPI (639-648)
apps/ui/src/lib/utils.ts (1)
  • truncateDescription (32-37)
apps/ui/src/components/views/board-view/kanban-board.tsx (4)
apps/ui/src/store/app-store.ts (2)
  • Feature (257-279)
  • useAppStore (967-2735)
libs/types/src/feature.ts (1)
  • Feature (46-81)
apps/ui/src/components/views/board-view/constants.ts (1)
  • COLUMNS (5-27)
apps/ui/src/hooks/use-responsive-kanban.ts (1)
  • useResponsiveKanban (48-194)
🔇 Additional comments (62)
apps/server/src/routes/agent/routes/model.ts (2)

14-22: LGTM: Improved validation clarity.

Splitting the validation into separate checks provides more specific error messages to API clients, making it easier to debug issues.


27-27: Error message updated for consistency.

The error message now aligns with the updated endpoint description, though given that the endpoint no longer performs model changes, this catch block would only handle validation errors.

libs/types/src/event.ts (1)

22-22: LGTM!

The new 'feature:updated' event type is appropriately placed among feature-related events and follows the existing naming convention. This enables the UI to react to feature state changes during the double-check workflow.

apps/ui/src/types/electron.d.ts (1)

444-453: LGTM!

The doubleCheckFeature method signature is well-designed and consistent with other AutoModeAPI methods. The return type appropriately includes verification-specific fields (passed, summary, discrepancies) alongside standard success/error handling.

apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts (2)

29-29: LGTM!

The new double_check column is correctly initialized in the column features map, consistent with the existing column structure.


83-89: LGTM!

Good logic here — features in double_check status remain in their designated column even when running, while still showing the running indicator via the isCurrentAutoTask prop. This correctly separates the visual status (column placement) from the execution state (running indicator).

libs/types/src/settings.ts (3)

73-97: LGTM!

Well-documented type definitions with clear JSDoc explanations. The DoubleCheckModelStrategy union type and DoubleCheckMode interface comprehensively cover the configuration options described in the PR objectives.


291-293: LGTM!

The doubleCheckMode field is correctly added to GlobalSettings with appropriate documentation.


470-474: LGTM!

Sensible default values: feature disabled by default, uses a different model for verification (reducing bias), and auto-triggers during Auto Mode for seamless integration.

apps/ui/src/styles/themes/blossom.css (1)

73-73: LGTM!

The purple/violet hue (280) provides good visual distinction from the in-progress (yellow) and waiting (orange) status colors. The lightness and chroma values are consistent with the theme's palette.

apps/ui/src/styles/themes/peach.css (1)

73-73: LGTM!

Consistent with other light themes. The purple hue provides good contrast against the peach theme's warm color palette.

apps/ui/src/styles/themes/dark.css (1)

84-84: LGTM!

The increased lightness (0.7) and chroma (0.18) appropriately adapt the double-check status color for dark mode visibility, following the same pattern as other status colors in this theme.

apps/ui/src/styles/themes/github.css (1)

73-73: LGTM!

The slightly lower lightness (0.6) aligns with the GitHub theme's more muted color palette while maintaining the consistent purple hue for the double-check status.

apps/ui/src/lib/http-api-client.ts (1)

599-608: LGTM! Clean API wrapper implementation.

The doubleCheckFeature method follows the established pattern for other Auto Mode API methods, with proper TypeScript typing and appropriate HTTP verb usage.

apps/ui/src/components/views/settings-view.tsx (1)

19-19: LGTM! Consistent integration of the new settings section.

The import and switch case follow the established pattern for other settings sections. The implementation is clean and maintainable.

Also applies to: 147-148

apps/ui/src/hooks/use-settings-migration.ts (1)

225-225: LGTM! Proper inclusion of doubleCheckMode in settings sync.

The addition follows the established pattern for syncing global settings fields. The deep merge logic is correctly handled server-side in settings-service.ts.

apps/ui/src/styles/themes/mint.css (1)

73-73: LGTM! Consistent status color addition.

The new --status-double-check custom property is properly placed among other status colors and follows the theme's color palette conventions.

apps/ui/src/styles/themes/gruvboxlight.css (1)

73-73: LGTM! Consistent theming across all CSS theme files.

The --status-double-check color token has been consistently added across multiple theme files (gruvboxlight, sepia, rose, and mint), each with theme-appropriate color adjustments while maintaining the same hue family. This ensures the double-check status will have proper visual representation across all themes.

apps/server/src/services/settings-service.ts (1)

137-140: LGTM! Proper deep merge implementation for nested settings.

The deep merge logic for doubleCheckMode correctly follows the same pattern established for keyboardShortcuts. This ensures that partial updates to the nested doubleCheckMode object won't inadvertently remove unspecified fields, maintaining proper defaults and backward compatibility.

Also applies to: 176-182

apps/ui/src/components/views/board-view/constants.ts (1)

12-16: LGTM! Well-positioned workflow column.

The new double_check column is correctly positioned in the workflow sequence and follows the established pattern for column definitions. The color variable reference aligns with the theme updates across the codebase.

apps/ui/src/styles/themes/snow.css (1)

73-73: LGTM! Consistent theme color addition.

The new status color variable follows the theme's color palette and format conventions.

apps/ui/src/components/views/settings-view/double-check/index.ts (1)

1-1: LGTM! Standard barrel export pattern.

The export follows the established pattern for component modules.

apps/ui/src/styles/themes/sunset.css (1)

82-82: LGTM! Theme-appropriate color addition.

The color value fits well within the Sunset theme's palette and maintains consistency with other status colors.

apps/ui/src/styles/themes/sand.css (1)

73-73: LGTM! Consistent theme integration.

The status color addition maintains the Sand theme's color harmony.

apps/ui/src/styles/themes/lavender.css (1)

73-73: LGTM! Theme-consistent color value.

The purple-hued status color aligns perfectly with the Lavender theme's soft purple/lavender palette.

apps/ui/src/styles/themes/paper.css (1)

73-73: LGTM! Clean minimal theme addition.

The status color maintains the Paper theme's clean and minimal aesthetic.

apps/ui/src/components/views/settings-view/config/navigation.ts (2)

12-12: LGTM! Appropriate icon import.

The CheckCheck icon from lucide-react is semantically appropriate for the double-check feature.


32-32: LGTM! Well-structured navigation item.

The new navigation item follows the established pattern and uses consistent kebab-case naming for the id. The positioning before the Danger Zone is logical for a feature-related setting.

apps/server/src/routes/auto-mode/index.ts (1)

20-20: LGTM! Clean integration of the double-check feature route.

The new route follows the established pattern with appropriate path validation for projectPath. The handler performs its own validation for featureId (as seen in the relevant code snippets), which is correct since featureId is not a file path and doesn't require path traversal protection.

Also applies to: 67-71

apps/ui/src/styles/themes/forest.css (1)

73-73: LGTM! Consistent status color addition.

The new --status-double-check variable is properly placed within the status color group and uses an appropriate purple hue (280) that visually distinguishes it from other status colors in the Forest theme.

apps/ui/src/components/views/settings-view/hooks/use-settings-view.ts (1)

12-12: LGTM! Clean type extension.

The addition of 'double-check' to the SettingsViewId union type properly enables navigation to the new Double-Check settings section and follows the existing pattern.

apps/ui/src/styles/themes/ocean.css (1)

73-73: LGTM! Consistent theme extension.

The --status-double-check variable addition matches the Ocean theme's color palette and maintains consistency with other status color definitions.

apps/ui/src/lib/electron.ts (1)

326-335: LGTM! Well-structured API method addition.

The doubleCheckFeature method follows the established pattern of other AutoModeAPI methods with appropriate parameter types and a comprehensive return type that includes both success and error states, along with optional verification details (passed, summary, discrepancies).

apps/ui/src/styles/themes/nordlight.css (1)

73-73: LGTM! Theme-appropriate color adjustment.

The --status-double-check variable is properly adjusted for the Nord Light theme with slightly lower chroma and lightness values that harmonize with the theme's softer color palette.

apps/ui/src/styles/themes/cream.css (1)

82-82: LGTM! Warm theme color harmony.

The --status-double-check variable is appropriately adjusted for the Cream theme's warm color palette while maintaining the purple hue (280) that distinguishes the double-check status across all themes.

apps/ui/src/styles/themes/sky.css (1)

73-73: LGTM! Sky theme integration complete.

The --status-double-check variable is properly integrated into the Sky theme with appropriate color values that maintain visual consistency with the theme's light blue color scheme.

apps/ui/src/styles/themes/solarizedlight.css (1)

73-73: LGTM!

The new --status-double-check color token is well-chosen. The purple hue (280) provides good visual distinction from existing status colors and maintains consistency with the overall theme palette.

apps/ui/src/styles/themes/gray.css (1)

82-82: LGTM!

The color value is appropriately adjusted for the gray theme while maintaining the same purple hue (280) as other themes for consistency.

libs/types/src/feature.ts (2)

79-79: LGTM!

The optional doubleCheckResult field integrates cleanly with the existing Feature interface without breaking changes.


83-89: LGTM!

The new double_check status extends the workflow appropriately and aligns with the documented feature flow: implementation → double_check → waiting_approval/backlog.

apps/server/src/types/settings.ts (1)

15-16: LGTM!

Clean re-export of double-check types maintains consistency with the existing re-export pattern in this file.

apps/ui/src/styles/global.css (2)

115-115: LGTM!

The color alias follows the established pattern for status tokens and integrates properly with the theme system.


193-193: LGTM!

The light and dark mode values are well-balanced. The dark mode uses higher lightness (0.7 vs 0.6) which ensures proper contrast on dark backgrounds, following best practices for accessible color systems.

Also applies to: 292-292

apps/server/src/index.ts (1)

117-117: LGTM!

Clean dependency injection of SettingsService into AutoModeService. This enables the double-check workflow to access global settings while maintaining testability and clear separation of concerns.

libs/types/src/index.ts (2)

19-25: LGTM!

The export of DoubleCheckResult properly expands the public type surface for the double-check feature.


55-62: LGTM!

Clean addition of double-check configuration types to the public settings API surface.

apps/server/src/routes/auto-mode/routes/double-check-feature.ts (1)

12-23: Path validation is already in place via middleware; focus type guard addition on featureId.

The /double-check-feature route already applies the validatePathParams('projectPath') middleware (line 69 in auto-mode/index.ts), which validates the projectPath using the validatePath() function from '@automaker/platform'. This middleware prevents path traversal attacks before the handler is invoked.

However, featureId lacks runtime validation. Add a type guard to ensure it's a non-empty string:

if (!projectPath || !featureId) {
+ if (!projectPath || !featureId || typeof featureId !== 'string') {

Likely an incorrect or invalid review comment.

apps/ui/src/components/views/board-view/kanban-board.tsx (1)

45-46: Double-check callbacks are cleanly plumbed through KanbanBoard

onDoubleCheck and onSkipDoubleCheck are threaded into the props and down to KanbanCard consistently; the board stays nicely declarative and keeps action logic in the hooks layer.

Also applies to: 79-80, 203-204

apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx (1)

28-29: Draggability and double-check callbacks are wired correctly

Including double_check in isDraggable and threading onDoubleCheck/onSkipDoubleCheck through to CardActions matches the updated Feature['status'] union and board workflows. No issues spotted with the prop surface or drag behavior.

Also applies to: 50-58, 70-75, 168-188

apps/ui/src/store/app-store.ts (1)

10-11: Double-Check Mode state and persistence are cohesive

The additions of double_check to Feature['status'], doubleCheckMode: DoubleCheckMode on AppState, the setDoubleCheckMode action, initial defaults, and inclusion in partialize all line up. Given the persist merge behavior ({ ...current, ...persisted }), older persisted stores will naturally pick up the new doubleCheckMode defaults without a dedicated migration. This looks ready to support the rest of the double-check workflow.

Also applies to: 267-273, 485-487, 758-760, 931-935, 1561-1565, 2709-2710

apps/ui/src/components/views/board-view.tsx (3)

598-848: Auto-mode scheduler priority for double-checks and resumes matches the intended flow

The updated auto-mode loop now:

  1. Respects maxConcurrency via availableSlots.
  2. Prioritizes double_check features when doubleCheckMode.enabled, honoring autoTriggerInAutoMode (auto-run vs. pause-until-manual).
  3. Uses featuresWithContextRef to resume in_progress features with saved context before touching new backlog work.
  4. Falls back to backlog selection with the same branch and dependency-filtering logic used elsewhere.

The use of refs (autoModeRunningRef, hookFeaturesRef, runningAutoTasksRef, handleStartImplementationRef, handleDoubleCheckRef, handleResumeFeatureRef, featuresWithContextRef) keeps the effect stable while still always calling the latest handlers, which is a solid pattern for this polling loop.


1122-1155: BoardView correctly propagates double-check handlers into KanbanBoard

handleDoubleCheck and handleSkipDoubleCheck are passed straight through to KanbanBoard, keeping BoardView focused on orchestration while the column/card components stay purely presentational. This aligns well with the existing separation of concerns.


560-582: No issue found. The doubleCheckFeature implementation in the AutoModeService properly emits the same AutoModeEvent types that the UI listener expects:

  • auto_mode_feature_start is emitted when double-check begins (cleanup removes from pending)
  • auto_mode_feature_complete is emitted on both pass and fail outcomes (cleanup removes from pending)
  • auto_mode_error is emitted when an exception occurs (cleanup removes from pending)

All three event types are already handled by the switch statement in board-view.tsx (lines 577-591), and all code paths through doubleCheckFeature emit one of these events. There is no risk of pending entries accumulating indefinitely.

Likely an incorrect or invalid review comment.

apps/server/src/services/auto-mode-service.ts (9)

346-358: LGTM: Clean dependency injection pattern.

The optional settingsService parameter and setter method enable flexible initialization while maintaining backward compatibility.


375-395: LGTM: Clear status determination logic.

The method correctly prioritizes automated testing, then double-check, then manual approval. The unused _projectPath parameter follows the underscore convention for future extensibility.


423-493: LGTM: Well-structured verification prompt and title extraction.

The double-check prompt provides a comprehensive checklist, and the title extraction handles truncation gracefully.


666-700: LGTM: Proper result persistence and event emission.

The method correctly updates the feature with double-check results and emits the appropriate event.


1012-1030: LGTM: Proper integration of final status determination.

The double-check workflow is correctly integrated into feature execution, with appropriate status messages for user feedback.


1294-1309: LGTM: Consistent status handling in follow-up flow.

The follow-up feature completion correctly applies the same status determination logic.


1849-1862: LGTM: Proper status transition handling.

The justFinishedAt timestamp correctly marks when features complete implementation (entering double_check or waiting_approval), and doubleCheckResult is appropriately cleared when returning to the backlog for re-implementation.


1956-1987: LGTM: Clean helper for loading features by status.

The method follows the same pattern as loadPendingFeatures and correctly filters features by status.


397-421: Add fallback for empty differentModels array.

In the 'different' case (line 408-415), if differentModels is empty (edge case where all available models match usedModel), line 414 would return undefined, causing type issues.

🔎 Proposed fix
      case 'different': {
        // Select a different model from the one that implemented the feature
        const availableModels: AgentModel[] = ['opus', 'sonnet', 'haiku'];
        const usedModel = (feature.model as AgentModel) || 'sonnet';
        const differentModels = availableModels.filter((m) => m !== usedModel);
        // Prefer sonnet if available, otherwise use first different model
-       return differentModels.includes('sonnet') ? 'sonnet' : differentModels[0];
+       return differentModels.includes('sonnet') ? 'sonnet' : (differentModels[0] || 'sonnet');
      }

Likely an incorrect or invalid review comment.

Comment on lines +24 to +25
// Model changes are not yet implemented
res.json({ success: true, message: 'Model change acknowledged' });
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the model.ts file
find . -path "*apps/server/src/routes/agent/routes/model.ts" -type f

# List the directory structure to understand the layout
ls -la apps/server/src/routes/agent/routes/ 2>/dev/null || echo "Directory not found, searching for model.ts files"

# Search for model.ts files
fd "model\.ts$" apps/server/src/routes/agent/ 2>/dev/null || fd "model\.ts$" . --max-depth 10 2>/dev/null | grep -E "(agent|model)"

Repository: AutoMaker-Org/automaker

Length of output: 618


🏁 Script executed:

#!/bin/bash
# Read the model.ts file with line numbers
cat -n apps/server/src/routes/agent/routes/model.ts

Repository: AutoMaker-Org/automaker

Length of output: 1280


🏁 Script executed:

#!/bin/bash
# Search for setSessionModel usage throughout codebase
echo "=== AgentService.setSessionModel usage ==="
rg -n "setSessionModel" --type=ts --type=tsx -B2 -A2

echo -e "\n=== Check AgentService implementation ==="
find . -name "*agent-service*" -type f | head -5

echo -e "\n=== Search for /model endpoint calls in client code ==="
rg -n "\/model|\.post.*model" apps/client apps/web --type=ts --type=tsx -C2 2>/dev/null | head -40

echo -e "\n=== Check route registration for model endpoint ==="
rg -n "model" apps/server/src/routes/agent --type=ts -B1 -A1 | head -30

Repository: AutoMaker-Org/automaker

Length of output: 2225


🏁 Script executed:

#!/bin/bash
# Check AgentService implementation
echo "=== AgentService methods ===" 
cat -n apps/server/src/services/agent-service.ts | head -100

echo -e "\n=== Search for setSession or model-related methods ==="
rg -n "setSession|getSession" apps/server/src/services/agent-service.ts -B1 -A5

echo -e "\n=== Check route index to see how model handler is registered ==="
cat -n apps/server/src/routes/agent/index.ts

echo -e "\n=== Check tests for model endpoint ==="
rg -n "model.*endpoint\|POST.*model" apps/server/tests --type=ts -C2

Repository: AutoMaker-Org/automaker

Length of output: 5577


🏁 Script executed:

#!/bin/bash
# Look at the Session interface to understand model property
echo "=== Session interface definition ==="
cat -n apps/server/src/services/agent-service.ts | sed -n '33,53p'

# Check if setSessionModel was being called elsewhere before
echo -e "\n=== Full setSessionModel implementation ==="
rg -n "setSessionModel" apps/server/src/services/agent-service.ts -B1 -A10

# Check if there are any TODOs or FIXMEs related to model
echo -e "\n=== Search for TODOs/FIXMEs about model ==="
rg -n "TODO|FIXME" apps/server/src/routes/agent/routes/model.ts

# Check git log for recent changes to model.ts
echo -e "\n=== Recent git changes to model.ts ==="
git -C . log --oneline -10 -- "apps/server/src/routes/agent/routes/model.ts" 2>/dev/null || echo "Git log not available"

# Check if send.ts uses the model parameter
echo -e "\n=== How send.ts uses model parameter ==="
cat -n apps/server/src/routes/agent/routes/send.ts | sed -n '1,50p'

Repository: AutoMaker-Org/automaker

Length of output: 3172


🏁 Script executed:

#!/bin/bash
# Check the full sendMessage implementation to see if it uses model
echo "=== AgentService.sendMessage with model parameter ==="
rg -n "sendMessage" apps/server/src/services/agent-service.ts -B2 -A20 | head -60

# Check how the model parameter affects the agent execution
echo -e "\n=== Search for where model is used in message processing ==="
rg -n "model" apps/server/src/services/agent-service.ts | grep -E "model\?" || echo "No model usage found"

# Check tests to see what behavior is expected
echo -e "\n=== Test files for agent routes ==="
find apps/server/tests -name "*model*" -o -name "*agent*route*" 2>/dev/null | head -10

# Check the commit message for Double-Check Mode
echo -e "\n=== Recent commits (last 5) ==="
git -C . log --oneline -5 2>/dev/null || echo "Git not available"

Repository: AutoMaker-Org/automaker

Length of output: 1037


🏁 Script executed:

#!/bin/bash
# Check if there are any client calls to the /model endpoint
echo "=== Search client code for /model endpoint calls ==="
find apps/client apps/web -type f \( -name "*.ts" -o -name "*.js" \) 2>/dev/null | xargs grep -l "model" 2>/dev/null | head -5 | while read file; do
  echo "File: $file"
  grep -n "\/model\|setModel\|changeModel" "$file" 2>/dev/null | head -3
done

# Check the git diff for the model.ts file to see what was changed
echo -e "\n=== Git diff for model.ts in latest commit ==="
git -C . show 64c8623:apps/server/src/routes/agent/routes/model.ts 2>/dev/null || echo "Previous version not available"

echo -e "\n=== Check for any commented out code in model.ts ==="
cat -n apps/server/src/routes/agent/routes/model.ts | grep -i "agentService\|setSession"

# Check if there are integration tests
echo -e "\n=== Integration tests for agent routes ==="
find apps/server/tests -name "*.test.ts" -exec grep -l "model\|/model" {} \; 2>/dev/null

Repository: AutoMaker-Org/automaker

Length of output: 2069


🏁 Script executed:

#!/bin/bash
# Check the Double-Check Mode test to understand context
echo "=== Double-Check Mode test file (first 50 lines) ==="
head -50 apps/server/tests/unit/services/auto-mode-service-double-check.test.ts

# Check if there's any reference to model endpoint in tests
echo -e "\n=== All references to /model or model endpoint in tests ==="
rg -n "model.*endpoint\|POST.*model\|\/model" apps/server/tests --type=ts

# Check the PR description or commit message more fully
echo -e "\n=== Commit details for 64c8623 ==="
git -C . log --format=fuller 64c8623 2>/dev/null | head -30

# Check README or any documentation about model switching
echo -e "\n=== Check for documentation about model changes ==="
find . -name "README*" -o -name "*.md" 2>/dev/null | xargs grep -l "model" 2>/dev/null | head -3 | while read f; do
  echo "=== File: $f ==="
  grep -i "model.*change\|switch.*model\|POST.*model" "$f" 2>/dev/null | head -3
done

Repository: AutoMaker-Org/automaker

Length of output: 2258


🏁 Script executed:

#!/bin/bash
# Check the full commit message
echo "=== Full commit message ==="
git -C . log -1 --format="%B" 64c8623 2>/dev/null

# Check if model.ts was added or modified in this commit
echo -e "\n=== File status in commit ==="
git -C . diff-tree --no-commit-id --name-status -r 64c8623 2>/dev/null | grep -i model

# Check if there are any client API calls throughout the codebase
echo -e "\n=== All HTTP POST calls in client code ==="
find . -path ./node_modules -prune -o -type f \( -name "*.ts" -o -name "*.js" \) -exec grep -l "fetch.*POST\|axios.*post\|\.post(" {} \; 2>/dev/null | grep -E "(client|web)" | head -5

# Check if there's an API client or service that calls the model endpoint
echo -e "\n=== Search for API client files ==="
find apps/client apps/web -name "*api*" -o -name "*client*" 2>/dev/null | head -10

# Final check: see if send endpoint has any relation to model
echo -e "\n=== Full sendMessage implementation to see model usage ==="
rg -n "async sendMessage" apps/server/src/services/agent-service.ts -A 80 | head -100

Repository: AutoMaker-Org/automaker

Length of output: 3043


🏁 Script executed:

#!/bin/bash
# Check the http-api-client to see if /model endpoint is used there
echo "=== HTTP API Client implementation ==="
cat apps/ui/src/lib/http-api-client.ts

# Verify if there are any UI components calling the model endpoint
echo -e "\n=== Search UI for model endpoint usage ==="
find apps/ui/src -type f -name "*.ts" 2>/dev/null | xargs grep -l "model" 2>/dev/null | head -5

Repository: AutoMaker-Org/automaker

Length of output: 32541


🏁 Script executed:

#!/bin/bash
# Final verification - check if any code references the /model endpoint
echo "=== Direct references to /api/agent/model ==="
rg -r "api/agent/model" --type=ts --type=js . 2>/dev/null | head -20

# Check if model parameter in send is actually being used correctly
echo -e "\n=== How sendMessage uses the model parameter ==="
rg -n "async sendMessage" apps/server/src/services/agent-service.ts -A 50 | grep -E "model|session\.model" | head -10

Repository: AutoMaker-Org/automaker

Length of output: 7607


Endpoint returns success without performing any action.

The /model endpoint accepts sessionId and model parameters but never uses them—the _agentService parameter (underscore-prefixed) is unused, and the handler returns { success: true, message: '...' } unconditionally without calling setSessionModel(). This is deceptive: clients will believe the model was changed when it wasn't.

The AgentService.setSessionModel() method exists and works correctly (confirmed in lines 502-510), but the endpoint never invokes it. The model parameter CAN be changed via the /send endpoint (lines 136-138), which properly updates the session model—but the dedicated /model endpoint is non-functional and should either be completed or removed.

🤖 Prompt for AI Agents
In apps/server/src/routes/agent/routes/model.ts around lines 24-25, the endpoint
currently returns success without using the provided sessionId/model or the
injected _agentService; update the handler to validate sessionId and model, call
agentService.setSessionModel(sessionId, model) (remove the underscore to use the
parameter), await its result, and return a success response only if the call
succeeds; also add error handling to return appropriate 4xx/5xx responses on
validation failure or if setSessionModel throws/fails.

Comment on lines +495 to +664
/**
* Execute double-check verification on a feature
*/
async doubleCheckFeature(
projectPath: string,
featureId: string
): Promise<{ passed: boolean; summary?: string; discrepancies?: string[] }> {
const feature = await this.featureLoader.get(projectPath, featureId);
if (!feature) {
throw new Error(`Feature ${featureId} not found`);
}

if (feature.status !== 'double_check') {
throw new Error(`Feature ${featureId} is not in double_check status`);
}

const settings = await this.loadGlobalSettings();
if (!settings) {
throw new Error('Unable to load settings');
}

const model = this.getDoubleCheckModel(feature, settings);
const prompt = this.buildDoubleCheckPrompt(feature);
const modelString = resolveModelString(model, DEFAULT_MODELS.claude);

// Add to running features so UI shows it as active
const abortController = new AbortController();
this.runningFeatures.set(featureId, {
featureId,
projectPath,
worktreePath: null,
branchName: feature.branchName || null,
abortController,
isAutoMode: false, // Manual double-check, not auto mode
startTime: Date.now(),
});

// Emit start event so UI shows the running indicator
this.emitAutoModeEvent('auto_mode_feature_start', {
featureId,
projectPath,
});

this.emitAutoModeEvent('auto_mode_progress', {
featureId,
projectPath,
content: `Starting double-check verification with model: ${model}`,
});

try {
// Load context files for the project
const { formattedPrompt: contextFilesPrompt } = await loadContextFiles({
projectPath,
fsModule: secureFs as Parameters<typeof loadContextFiles>[0]['fsModule'],
});

// Get the provider for the model
const provider = ProviderFactory.getProviderForModel(modelString);

// Execute the double-check
const abortController = new AbortController();
const executeOptions: ExecuteOptions = {
prompt,
model: modelString,
cwd: projectPath,
maxTurns: 50, // Limited turns for verification
abortController,
systemPrompt: contextFilesPrompt || undefined,
};

const stream = provider.executeQuery(executeOptions);
let resultText = '';

// Collect the streaming response
for await (const msg of stream) {
if (msg.type === 'assistant' && msg.message?.content) {
for (const block of msg.message.content) {
if (block.type === 'text') {
resultText += block.text || '';
}
}
}
}
const passed = resultText.includes('[DOUBLE_CHECK_PASSED]');
const failed = resultText.includes('[DOUBLE_CHECK_FAILED]');

// Extract summary and discrepancies
let summary: string | undefined;
let discrepancies: string[] | undefined;

if (passed) {
const passedIndex = resultText.indexOf('[DOUBLE_CHECK_PASSED]');
summary = resultText.substring(passedIndex + '[DOUBLE_CHECK_PASSED]'.length).trim();
} else if (failed) {
const failedIndex = resultText.indexOf('[DOUBLE_CHECK_FAILED]');
const failedContent = resultText
.substring(failedIndex + '[DOUBLE_CHECK_FAILED]'.length)
.trim();
// Try to extract discrepancies as bullet points
const lines = failedContent
.split('\n')
.filter((l) => l.trim().startsWith('-') || l.trim().match(/^\d+\./));
discrepancies = lines
.map((l) => l.replace(/^[-\d.]+\s*/, '').trim())
.filter((l) => l.length > 0);
summary =
discrepancies.length > 0
? `Found ${discrepancies.length} issue(s)`
: failedContent.substring(0, 200);
}

// Create the double-check result
const doubleCheckResult: DoubleCheckResult = {
status: passed ? 'passed' : 'failed',
discrepancies: discrepancies,
checkedAt: new Date().toISOString(),
checkedBy: model,
originalModel: (feature.model as AgentModel) || 'sonnet',
summary: summary,
};

// Update feature with result and new status
// If double-check failed, send back to backlog so auto-mode can pick it up for re-implementation
const newStatus = passed ? 'waiting_approval' : 'backlog';
await this.updateFeatureWithDoubleCheckResult(
projectPath,
featureId,
doubleCheckResult,
newStatus
);

// Remove from running features
this.runningFeatures.delete(featureId);

// Emit appropriate event
if (passed) {
this.emitAutoModeEvent('auto_mode_feature_complete', {
featureId,
projectPath,
passes: true,
message: `Double-check passed: ${summary || 'No issues found'}`,
});
} else {
this.emitAutoModeEvent('auto_mode_feature_complete', {
featureId,
projectPath,
passes: false,
message: `Double-check failed: ${summary || 'Issues found'}`,
});
}

return { passed, summary, discrepancies };
} catch (error) {
// Remove from running features on error
this.runningFeatures.delete(featureId);

console.error(`[AutoMode] Double-check failed for ${featureId}:`, error);
const errorInfo = classifyError(error);

// Keep in double_check status on error
this.emitAutoModeEvent('auto_mode_error', {
featureId,
error: `Double-check failed: ${errorInfo.message}`,
errorType: errorInfo.type,
projectPath,
});

throw error;
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Abort controller shadowing prevents stopping double-check.

Line 555 creates a new AbortController that shadows the one created at line 521. The first controller is stored in runningFeatures (line 522-530), but the second is passed to executeOptions (line 562). As a result, calling stopFeature(featureId) would abort the wrong controller, and the double-check operation cannot be stopped.

🔎 Proposed fix
    const model = this.getDoubleCheckModel(feature, settings);
    const prompt = this.buildDoubleCheckPrompt(feature);
    const modelString = resolveModelString(model, DEFAULT_MODELS.claude);

    // Add to running features so UI shows it as active
    const abortController = new AbortController();
    this.runningFeatures.set(featureId, {
      featureId,
      projectPath,
      worktreePath: null,
      branchName: feature.branchName || null,
      abortController,
      isAutoMode: false, // Manual double-check, not auto mode
      startTime: Date.now(),
    });

    // ... emit events ...

    try {
      // Load context files for the project
      const { formattedPrompt: contextFilesPrompt } = await loadContextFiles({
        projectPath,
        fsModule: secureFs as Parameters<typeof loadContextFiles>[0]['fsModule'],
      });

      // Get the provider for the model
      const provider = ProviderFactory.getProviderForModel(modelString);

      // Execute the double-check
-     const abortController = new AbortController();
      const executeOptions: ExecuteOptions = {
        prompt,
        model: modelString,
        cwd: projectPath,
        maxTurns: 50, // Limited turns for verification
        abortController,
        systemPrompt: contextFilesPrompt || undefined,
      };
🤖 Prompt for AI Agents
In apps/server/src/services/auto-mode-service.ts around lines 495 to 664, the
AbortController created at line ~521 is shadowed by a second declaration around
line ~555, so the controller stored in runningFeatures is not the one passed to
provider.executeQuery; remove the second "const abortController = new
AbortController()" and reuse the earlier abortController when building
executeOptions so the same controller stored in runningFeatures is the one that
gets aborted by stopFeature(featureId); keep the rest of executeOptions the same
and ensure no other references expect the inner variable.

Comment on lines +747 to +794
// Check for features awaiting double-check (if auto-trigger is enabled)
const settings = await this.loadGlobalSettings();
const doubleCheckEnabled = settings?.doubleCheckMode?.enabled;
const autoTrigger = settings?.doubleCheckMode?.autoTriggerInAutoMode;
console.log('[AutoMode] Double-check settings:', {
enabled: doubleCheckEnabled,
autoTriggerInAutoMode: autoTrigger,
});

// Always check for double-check features first, regardless of auto-trigger setting
// This ensures double-check items are processed before new backlog items
const doubleCheckFeatures = await this.loadFeaturesWithStatus(
this.config!.projectPath,
'double_check'
);
console.log('[AutoMode] Found double-check features:', doubleCheckFeatures.length);

if (doubleCheckFeatures.length > 0 && doubleCheckEnabled) {
const nextDoubleCheck = doubleCheckFeatures.find(
(f: Feature) => !this.runningFeatures.has(f.id)
);

if (nextDoubleCheck) {
if (autoTrigger) {
console.log('[AutoMode] Auto-processing double-check feature:', nextDoubleCheck.id);
// Run double-check in background
this.doubleCheckFeature(this.config!.projectPath, nextDoubleCheck.id).catch(
(error) => {
console.error(
`[AutoMode] Double-check feature ${nextDoubleCheck.id} error:`,
error
);
}
);
await this.sleep(2000);
continue;
} else {
// Double-check items exist but auto-trigger is off - wait for manual trigger
// Don't start new backlog items while double-check items are pending
console.log(
'[AutoMode] Double-check feature waiting for manual trigger:',
nextDoubleCheck.id
);
await this.sleep(5000);
continue;
}
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider handling features stuck in double_check status when mode is disabled.

Lines 758-764 always load double_check features but only process them if doubleCheckEnabled=true. If double-check mode is disabled after features are already in double_check status, those features will be skipped by the auto-loop and remain stuck.

🔎 Suggested handling

Consider either:

  1. Automatically moving double_check features back to waiting_approval when double-check mode is disabled, or
  2. Processing them as waiting_approval regardless of the setting (since they're already in the queue).

Example approach:

  // Always check for double-check features first, regardless of auto-trigger setting
  // This ensures double-check items are processed before new backlog items
  const doubleCheckFeatures = await this.loadFeaturesWithStatus(
    this.config!.projectPath,
    'double_check'
  );
  console.log('[AutoMode] Found double-check features:', doubleCheckFeatures.length);

- if (doubleCheckFeatures.length > 0 && doubleCheckEnabled) {
+ if (doubleCheckFeatures.length > 0) {
+   if (!doubleCheckEnabled) {
+     // Double-check disabled but features are stuck - move to waiting_approval
+     console.log('[AutoMode] Double-check disabled, moving features to waiting_approval');
+     for (const feature of doubleCheckFeatures) {
+       await this.updateFeatureStatus(this.config!.projectPath, feature.id, 'waiting_approval');
+     }
+     continue;
+   }
    const nextDoubleCheck = doubleCheckFeatures.find(
      (f: Feature) => !this.runningFeatures.has(f.id)
    );

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/server/src/services/auto-mode-service.ts around lines 747 to 794, the
loop currently always loads features with status "double_check" but only
processes them when doubleCheckEnabled is true, which leaves features stuck when
mode is later disabled; modify the logic so that when doubleCheckEnabled is
false and there are features in "double_check" you either (A) programmatically
move those features back to "waiting_approval" by calling the existing
status-update method (persist the change and log it) or (B) treat them as
"waiting_approval" for processing by the auto-loop (i.e., enqueue/process them
immediately as if their status were waiting_approval) — implement one of these
flows, add clear logs for the transition, and ensure any DB/feature-cache is
updated so they are not ignored on subsequent iterations.

@Shironex Shironex added Enhancement Improvements to existing functionality or UI. Testers-Requested Request for others to test an enhancement or bug fix/etc. Do Not Merge Use this label if something should not be merged. labels Dec 23, 2025
@NomadicDaddy NomadicDaddy deleted the feature/double-check-mode branch December 28, 2025 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Use this label if something should not be merged. Enhancement Improvements to existing functionality or UI. Testers-Requested Request for others to test an enhancement or bug fix/etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants