Skip to content

fix: recover watcher rebuilds and optional doctor clients - #646

Merged
mohanagy merged 4 commits into
mainfrom
agent/issues-619-645-release
Aug 11, 2026
Merged

mohanagy merged 4 commits into
mainfrom
agent/issues-619-645-release

Conversation

@mohanagy

@mohanagy mohanagy commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Closes #619.
Closes #645.

What changed:

  • keep the watcher alive after transient rebuild failures, retry automatically, and clear the failure after a successful rebuild
  • retain fail-closed graph reads while freshness is not guaranteed
  • treat never-installed clients as informational when another agent integration is complete
  • keep partial or stale attempted integrations actionable

Validation:

  • 63 focused doctor/watch tests pass
  • typecheck passes
  • build passes
  • four unrelated full-suite timeout cases pass in isolated reruns; fresh PR CI is the merge gate

Summary by CodeRabbit

  • Bug Fixes

    • Automatic refreshes now recover from temporary rebuild failures through bounded retries without stopping the watcher.
    • Doctor checks now distinguish configured, partially configured, and uninstalled optional agent integrations.
    • Healthy installations no longer show unnecessary remediation steps for uninstalled optional agents.
    • Stale agent configurations now receive actionable attention states and reinstall guidance.
  • Documentation

    • Added unreleased release notes covering refresh recovery and improved doctor behavior.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a19cd13f-66ce-41fc-a8fb-ed439e03a9ff

📥 Commits

Reviewing files that changed from the base of the PR and between 724abb7 and cbad2d0.

📒 Files selected for processing (1)
  • tests/unit/watch.test.ts

📝 Walkthrough

Walkthrough

Doctor now treats uninstalled optional agents as informational. Automatic rebuild failures trigger bounded retries while the watcher continues running. Tests cover Claude-only health, stale agent configuration, and transient rebuild recovery. The changelog documents both fixes.

Changes

Doctor health evaluation

Layer / File(s) Summary
Agent remediation and health checks
src/infrastructure/doctor.ts, tests/unit/doctor.test.ts
Doctor adds default installation suggestions for unconfigured agents. Individual suggestions target partial configurations. Health checks evaluate configured or attempted agents. Tests cover healthy Claude-only and stale Gemini configurations.

Watcher rebuild recovery

Layer / File(s) Summary
Automatic rebuild retry flow
src/infrastructure/watch.ts, tests/unit/watch.test.ts, CHANGELOG.md
The watcher persists retry state after failed automatic rebuilds, defers periodic reconciliation, notifies the user, and continues monitoring. Tests verify recovery on the second attempt and final completion state. The changelog records both fixes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Watcher
  participant AutomaticRebuild
  participant WatcherState
  participant UserNotification
  Watcher->>AutomaticRebuild: attempt rebuild
  AutomaticRebuild-->>Watcher: return failure
  Watcher->>WatcherState: persist retry state
  Watcher->>UserNotification: report retry-specific failure
  Watcher->>Watcher: schedule bounded retry
  Watcher->>AutomaticRebuild: retry rebuild
  AutomaticRebuild-->>Watcher: return success
  Watcher->>WatcherState: persist stopped, complete state
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the watcher recovery and optional doctor client changes.
Description check ✅ Passed The description explains the changes, testing, related issues, and focused scope, although it does not reproduce the template headings or checkboxes.
Linked Issues check ✅ Passed The changes address optional-client diagnostics in #619 and resilient watcher rebuild recovery with fail-closed reads in #645.
Out of Scope Changes check ✅ Passed The code, tests, and changelog changes are directly related to the linked issues and stated watcher and doctor objectives.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/issues-619-645-release

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/infrastructure/doctor.ts`:
- Around line 561-563: Update the Gemini command-selection branch in the doctor
flow to handle both partial and stale Gemini MCP statuses, matching the existing
stale-MCP handling for Claude, Cursor, and Copilot while preserving madar gemini
install for partial status. Add a regression test covering Claude configured
alongside stale Gemini MCP state and assert that the Gemini install command is
emitted.

In `@src/infrastructure/watch.ts`:
- Around line 1103-1109: The reconciliation loop around runNotify and
recordSuccessfulReconciliation must preserve failed freshness until the
scheduled rebuild succeeds. Update the retry scheduling flow to keep
state.coverage incomplete and failure_reason intact, synchronize local
nextReconciliationAt with persisted state.next_reconciliation_at, and ensure
retry processing precedes normal reconciliation or prevents it from clearing the
failure while rebuilt is false. Clear the failure and restore complete coverage
only after a successful rebuild, and add a regression assertion covering
persisted state during the retry window.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1733a008-5e18-49b2-aa33-ddfb42b76be4

📥 Commits

Reviewing files that changed from the base of the PR and between 52985a4 and 161baac.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • src/infrastructure/doctor.ts
  • src/infrastructure/watch.ts
  • tests/unit/doctor.test.ts
  • tests/unit/watch.test.ts

Comment thread src/infrastructure/doctor.ts
Comment thread src/infrastructure/watch.ts
@mohanagy
mohanagy force-pushed the agent/issues-619-645-release branch from 724abb7 to 3adc289 Compare August 11, 2026 14:50

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
tests/unit/watch.test.ts (1)

779-781: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Make the retry test state-driven.

The fixed delays do not identify watcher readiness or the retry transition. The second rebuild also aborts the watcher before the test observes the successful state. Wait for the persisted failed state, let the second rebuild return without aborting, assert coverage: 'complete' and failure_reason: null while the watcher is active, then abort and assert status: 'stopped'.

Based on learnings: hosted CI tests should focus on correctness and portability rather than cold, single-sample wall-clock timing assertions.

Also applies to: 796-818

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/watch.test.ts` around lines 779 - 781, Update the retry test
around the later Git visibility snapshot failure to use state-driven waits
instead of fixed delays: wait for the persisted failed state, allow the second
rebuild to complete without aborting, assert the active watcher has coverage set
to complete and failure_reason set to null, then abort it and assert status
stopped.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/watch.test.ts`:
- Around line 779-781: Update the retry test around the later Git visibility
snapshot failure to use state-driven waits instead of fixed delays: wait for the
persisted failed state, allow the second rebuild to complete without aborting,
assert the active watcher has coverage set to complete and failure_reason set to
null, then abort it and assert status stopped.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: eef648ff-c792-4f2d-a048-fcdb5ecf9c60

📥 Commits

Reviewing files that changed from the base of the PR and between 161baac and 724abb7.

📒 Files selected for processing (4)
  • src/infrastructure/doctor.ts
  • src/infrastructure/watch.ts
  • tests/unit/doctor.test.ts
  • tests/unit/watch.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/doctor.test.ts
  • src/infrastructure/watch.ts

@mohanagy
mohanagy merged commit e7c6756 into main Aug 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant