Skip to content

Reliability follow-ups: referenced lifecycle timers, shared-signal token exchange#891

Merged
arul28 merged 1 commit into
mainfrom
ade/start-skill-both-macbook-mac-01881577
Jul 24, 2026
Merged

Reliability follow-ups: referenced lifecycle timers, shared-signal token exchange#891
arul28 merged 1 commit into
mainfrom
ade/start-skill-both-macbook-mac-01881577

Conversation

@arul28

@arul28 arul28 commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Three verified P1s from PR #889's final review round, fixed post-merge before the release:

  • Awaited termination/handover timers in serviceManager stay referenced — an unref'd awaited timer could let a standalone ade serve --install-service exit before SIGKILL escalation and launchctl load while repairing a wedged brain.
  • The coalesced session token exchange now actually uses the service-owned shared signal (one call site missed in Reliability: guaranteed brain updates, wedge-proof event loop, verified handover, AEAD account-connect fix #889), so a fast-aborting caller can't kill the refresh other callers await.
  • The env-token refresh single-flight is released only by the shared exchange settling; an aborting caller no longer clears it early and triggers a competing OAuth exchange with the same rotating refresh token.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added ade doctor health checks with readable status tables, JSON output, and optional online version checks.
    • Added runtime recovery notices and richer runtime health/activity details in the desktop app.
    • Added update banners for ready, parked, and automatically scheduled updates, including cancellation controls.
    • Improved remote machine publishing health visibility and port-conflict recovery.
    • Added stronger account pairing compatibility through negotiated encryption support.
  • Bug Fixes

    • Improved cancellation and timeout handling for account refreshes, remote commands, GitHub requests, and service handoffs.
    • Added runtime freshness monitoring and recovery safeguards for stalled or outdated services.

Greptile Summary

This PR updates service lifecycle waits and account token refresh cancellation. The main changes are:

  • Keeps awaited service termination and launchd handover timers referenced.
  • Uses shared cancellation for coalesced account refresh token exchanges.
  • Releases the env-token refresh single-flight only when the shared refresh settles.

Confidence Score: 4/5

One contained account refresh bug should be fixed before merging.

The lifecycle timer changes are narrow and safe. The account refresh changes mostly preserve shared cancellation, but one env-token fallback can still let an aborted caller fail shared work.

apps/ade-cli/src/services/account/accountAuthService.ts

T-Rex T-Rex Logs

What T-Rex did

  • Reviewed static verification of the shared fallback isolation; runtime evidence was blocked by the step limit, and static inspection confirmed the fallback calls getAccessTokenWithSignal({}, signal) at line 1806.
  • Executed a verbose Vitest run for the ADE CLI tests, including common.test.ts and accountAuthService.test.ts, which completed with exit code 0, 2 test files and 112 tests passing in about 1.04 seconds.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
apps/ade-cli/src/serviceManager/common.ts Keeps the awaited async termination poll timer referenced so SIGKILL escalation cannot be skipped by process exit.
apps/ade-cli/src/serviceManager/installLaunchd.ts Keeps launchd handover sleep timers referenced during service repair polling.
apps/ade-cli/src/services/account/accountAuthService.ts Moves token refresh single-flight cleanup to shared promise settlement and uses shared cancellation for refresh calls, but one fallback retry still captures an individual caller signal.

Sequence Diagram

sequenceDiagram
participant Caller as Token caller
participant Join as getAccessToken join
participant Shared as Shared refresh promise
participant OAuth as OAuth token endpoint
participant Store as Env/session state

Caller->>Join: getAccessToken(signal)
Join->>Shared: create or join env/session refresh
Shared->>OAuth: refresh_token exchange(shared signal)
OAuth-->>Shared: access/refresh token
Shared->>Store: persist/update refreshed session
Shared-->>Join: shared result settles
Join-->>Caller: result or caller-local abort
Loading

Comments Outside Diff (1)

  1. apps/ade-cli/src/services/account/accountAuthService.ts, line 1803-1806 (link)

    P1 Keep shared fallback isolated
    This fallback re-enters getAccessTokenWithSignal with the initiating caller's signal. When the env credential changes during the shared refresh after that caller has aborted, the shared refreshPromise rejects with that caller's abort instead of consuming the newer credential for other waiters. Use the shared signal for this internal retry so only the shared timeout controls it.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/ade-cli/src/services/account/accountAuthService.ts
    Line: 1803-1806
    
    Comment:
    **Keep shared fallback isolated**
    This fallback re-enters `getAccessTokenWithSignal` with the initiating caller's `signal`. When the env credential changes during the shared refresh after that caller has aborted, the shared `refreshPromise` rejects with that caller's abort instead of consuming the newer credential for other waiters. Use the shared signal for this internal retry so only the shared timeout controls it.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/ade-cli/src/services/account/accountAuthService.ts:1803-1806
**Keep shared fallback isolated**
This fallback re-enters `getAccessTokenWithSignal` with the initiating caller's `signal`. When the env credential changes during the shared refresh after that caller has aborted, the shared `refreshPromise` rejects with that caller's abort instead of consuming the newer credential for other waiters. Use the shared signal for this internal retry so only the shared timeout controls it.

```suggestion
            // The credential changed while this process was refreshing. The
            // replacement is already newer than the request we started, so
            // consume it normally instead of force-rotating it again.
            return getAccessTokenWithSignal({}, envSharedSignal);
```

Reviews (2): Last reviewed commit: "fix(reliability): referenced lifecycle t..." | Re-trigger Greptile

@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jul 24, 2026 3:30am

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Runtime diagnostics and reliability

Layer / File(s) Summary
Doctor and runtime monitoring
apps/ade-cli/src/commands/doctor.ts, apps/ade-cli/src/cli.ts, apps/ade-cli/src/services/runtime/*
Adds structured ade doctor checks, runtime compatibility/status reporting, brain watchdog recovery data, freshness monitoring, logging, and activity summaries.
Sync cancellation and pairing
apps/ade-cli/src/services/sync/*, apps/desktop/src/shared/sync/*, apps/desktop/src/main/services/remoteRuntime/*
Adds abort propagation for remote operations, stale port-holder diagnosis, slow-command warnings, and negotiated ChaCha20/AES adoption-channel encryption.
Account publishing health
apps/ade-cli/src/services/account/*, apps/ade-cli/src/services/sync/abortSignal.ts
Adds shared refresh cancellation, per-leg publish timing, timeout classification, sustained-failure analytics, and richer publisher health state.

Desktop runtime and updates

Layer / File(s) Summary
Runtime status integration
apps/desktop/src/main/services/localRuntime/*, apps/desktop/src/main/main.ts, apps/desktop/src/shared/*
Publishes runtime health, wedge, protocol, activity, and status-change data through the desktop process and IPC bridge.
Auto-update lifecycle
apps/desktop/src/main/services/updates/*, apps/desktop/src/main/main.ts
Adds parked install failures, rollback handling, idle auto-apply scheduling, cancellation, quit deadlines, and forced handoff escalation.
Desktop UI and release data
apps/desktop/src/renderer/components/*, apps/desktop/src/main/services/github/*
Adds update/recovery notices, runtime and publish-health displays, richer About version state, release lookup extraction, and GitHub response-body timeouts.
Analytics and observability
apps/account-directory/wrangler.jsonc, apps/desktop/src/main/services/analytics/*, scripts/posthog/*
Enables Cloudflare observability and registers, sanitizes, budgets, visualizes, and tests new update and reliability analytics events.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • arul28/ADE#889: Related runtime diagnostics, ade doctor, compatibility, and sync wiring.
  • arul28/ADE#827: Related account machine publishing and pairing changes.
  • arul28/ADE#497: Related desktop auto-update service initialization and lifecycle behavior.

Suggested labels: desktop, docs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.42% 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
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main reliability fixes around referenced timers and shared-signal token exchange, even if it omits one secondary detail.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/start-skill-both-macbook-mac-01881577

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

❤️ Share

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

Comment thread apps/desktop/src/main/services/updates/autoUpdateService.ts

@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

🧹 Nitpick comments (6)
apps/account-directory/wrangler.jsonc (1)

8-8: 🚀 Performance & Scalability | 🔵 Trivial

Confirm 100% trace sampling is intentional.

head_sampling_rate: 1 traces every request/invocation (including the once-a-minute cron). This gives full observability but increases ingested trace volume/cost proportionally to traffic. Worth a deliberate call now rather than an accidental cost surprise later.

🤖 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 `@apps/account-directory/wrangler.jsonc` at line 8, Confirm that
head_sampling_rate in the observability configuration is intentionally set to 1
for 100% trace sampling; if full sampling is not explicitly required, replace it
with the approved lower sampling rate while preserving observability for
scheduled and request-driven invocations.
scripts/posthog/dashboard-spec.mjs (1)

510-525: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider whether UPDATE_AUTO_APPLY_CANCELLED belongs in this incident chart.

The new "reliability-incidents" insight tracks install-aborted, quit-escalated, and auto-applied outcomes, but omits UPDATE_AUTO_APPLY_CANCELLED. If cancellations are a signal worth watching alongside aborts/escalations, consider adding it; if intentionally excluded (user-initiated, not a failure), no change needed.

🤖 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 `@scripts/posthog/dashboard-spec.mjs` around lines 510 - 525, Decide whether
UPDATE_AUTO_APPLY_CANCELLED represents a reliability incident alongside the
existing update outcome events in the reliability-incidents insight. If it
should be tracked, add eventNode(UPDATE_AUTO_APPLY_CANCELLED, ...) to the
series; otherwise leave the chart unchanged and preserve the current intentional
exclusion.
apps/desktop/src/shared/types/productAnalytics.ts (1)

13-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Event catalog is duplicated across three independent sources with no shared source of truth. All three files currently agree on the six new ade_update_*/ade_brain_recovered/ade_publish_failing event names, but each maintains its own hand-typed copy, so a future rename/typo in any one of them would silently desync the desktop allowlist from the PostHog dashboard spec.

  • apps/desktop/src/shared/types/productAnalytics.ts#L13-L18: canonical TS event-name union — the natural anchor if a shared source were introduced.
  • apps/desktop/src/main/services/analytics/productAnalyticsPolicy.ts#L16-L21: could import event names from productAnalytics.ts instead of re-listing them.
  • scripts/posthog/dashboard-spec.mjs#L14-L19: a standalone JS script (different language/build target) so full unification may require a generated/shared JSON manifest rather than a direct import.
🤖 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 `@apps/desktop/src/shared/types/productAnalytics.ts` around lines 13 - 18,
Introduce one shared event-name manifest as the source of truth for the catalog,
using productAnalytics.ts as the canonical type anchor. Update
productAnalyticsPolicy.ts to derive or import its allowlist from that manifest,
and update scripts/posthog/dashboard-spec.mjs to consume the same manifest
through a compatible generated or shared JSON format; remove the duplicated
hand-typed event lists at all three sites.
apps/ade-cli/src/commands/doctor.ts (1)

540-559: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use DEFAULT_SYNC_HOST_PORT instead of the literal 8787.

The rest of the file (including the portDiagnoses gating at Line 707) keys off DEFAULT_SYNC_HOST_PORT, but this row hardcodes 8787 in both the ok condition and the detail strings. If the default ever changes, syncPortRow would diverge from the diagnosis logic and mislabel the bound port.

♻️ Proposed change
-  if (input.syncPort === 8787) {
+  if (input.syncPort === DEFAULT_SYNC_HOST_PORT) {
     return {
       key: "sync_port",
       label: "Sync port",
       status: "ok",
-      detail: "bound on 8787",
+      detail: `bound on ${DEFAULT_SYNC_HOST_PORT}`,
     };
   }
   const holders = input.portDiagnoses.flatMap((diagnosis) =>
     diagnosis.holders.map((holder) =>
       `${diagnosis.port}: pid ${holder.pid}${holder.command ? ` ${holder.command}` : ""}`,
     ),
   );
   return {
     key: "sync_port",
     label: "Sync port",
     status: "warn",
-    detail: `bound on ${input.syncPort} instead of 8787${
+    detail: `bound on ${input.syncPort} instead of ${DEFAULT_SYNC_HOST_PORT}${
🤖 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 `@apps/ade-cli/src/commands/doctor.ts` around lines 540 - 559, Update the
syncPortRow logic to use DEFAULT_SYNC_HOST_PORT instead of the hardcoded 8787 in
the equality check and all related detail strings, keeping the existing status
and holder-reporting behavior unchanged.
apps/ade-cli/src/multiProjectRpcServer.ts (1)

1060-1065: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated runtimeInfo extras block across two handlers.

The minCompatibleProtocol/protocolVersion/multiProject/pid/uptimeMs block is duplicated verbatim in the ade/initialize and runtime/info/machineInfo.get handlers. Since both already call resolveRuntimeStatus() and resolveRuntimeEnvInfo(), consider factoring this into a small shared helper (e.g. buildRuntimeInfoExtras()) to avoid the two sites drifting out of sync on a future change (e.g. if protocolVersion semantics or uptimeMs rounding is later revisited).

♻️ Proposed refactor
+  const buildRuntimeInfoExtras = () => ({
+    ...resolveRuntimeStatus(),
+    minCompatibleProtocol: RUNTIME_COMPAT_LEVEL,
+    protocolVersion: RUNTIME_COMPAT_LEVEL,
+    multiProject: true,
+    pid: process.pid,
+    uptimeMs: Math.max(0, Math.round(process.uptime() * 1_000)),
+  });
+
   // ade/initialize:
   runtimeInfo: {
     name: "ade-rpc",
     version: options.serverVersion,
     ...resolveRuntimeEnvInfo(),
-    ...resolveRuntimeStatus(),
-    minCompatibleProtocol: RUNTIME_COMPAT_LEVEL,
-    protocolVersion: RUNTIME_COMPAT_LEVEL,
-    multiProject: true,
-    pid: process.pid,
-    uptimeMs: Math.max(0, Math.round(process.uptime() * 1_000)),
+    ...buildRuntimeInfoExtras(),
   },
   // runtime/info / machineInfo.get:
   runtimeInfo: {
     name: "ade-rpc",
     version: options.serverVersion,
     ...envInfo,
-    ...resolveRuntimeStatus(),
-    minCompatibleProtocol: RUNTIME_COMPAT_LEVEL,
-    protocolVersion: RUNTIME_COMPAT_LEVEL,
-    multiProject: true,
-    pid: process.pid,
-    uptimeMs: Math.max(0, Math.round(process.uptime() * 1_000)),
+    ...buildRuntimeInfoExtras(),
   },

Also applies to: 1116-1121

🤖 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 `@apps/ade-cli/src/multiProjectRpcServer.ts` around lines 1060 - 1065, Factor
the duplicated runtime metadata object out of the ade/initialize and
runtime/info/machineInfo.get handlers into a shared helper such as
buildRuntimeInfoExtras(). Have both handlers spread the helper result alongside
resolveRuntimeStatus() and resolveRuntimeEnvInfo(), preserving the existing
minCompatibleProtocol, protocolVersion, multiProject, pid, and uptimeMs values
and uptime rounding.
apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts (1)

1325-1327: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Bound activitySummary() with an explicit RPC timeout.

activitySummary() is used by createAutoUpdateService through localRuntimePool.activitySummary(), and that call path has no Promise timeout, timebox, or Promise.race around getRuntimeActivitySummary. Since callSync() currently maps directly to entry.client.call(method, params) without options, rely on the RPC client default rather than a short activity-check bound; add an explicit short timeout, or at least use/define one in autoUpdateService.ts for this idle poll.

🤖 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 `@apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts`
around lines 1325 - 1327, Update localRuntimeConnectionPool.activitySummary() to
enforce an explicit short RPC timeout when calling runtime.activitySummary,
using an existing timeout constant or a clearly defined idle-poll timeout from
autoUpdateService.ts. Ensure the timeout is passed through the callSync RPC
options while preserving the RuntimeActivitySummary return behavior.
🤖 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 `@apps/desktop/src/main/services/github/adeReleaseFeed.ts`:
- Around line 24-50: Update fetchAdeLatestRelease so its default global fetch
path uses a bounded abort signal, matching the timeout pattern in
githubService.ts. Apply the signal only when no custom fetchImpl is supplied,
preserving custom fetch behavior and the existing response/error handling.

In `@apps/desktop/src/main/services/updates/autoUpdateService.ts`:
- Around line 1039-1080: Update abortInstall to seed autoApplySuppressedUntil
when the parked abort reason represents a refresh, handoff, preflight, or
timeout/setup failure, preventing idle auto-apply from restarting during the
suppression window. Preserve normal ready-state cleanup for other aborts, and
explicitly clear the suppression timestamp for user-initiated cancellation.

---

Nitpick comments:
In `@apps/account-directory/wrangler.jsonc`:
- Line 8: Confirm that head_sampling_rate in the observability configuration is
intentionally set to 1 for 100% trace sampling; if full sampling is not
explicitly required, replace it with the approved lower sampling rate while
preserving observability for scheduled and request-driven invocations.

In `@apps/ade-cli/src/commands/doctor.ts`:
- Around line 540-559: Update the syncPortRow logic to use
DEFAULT_SYNC_HOST_PORT instead of the hardcoded 8787 in the equality check and
all related detail strings, keeping the existing status and holder-reporting
behavior unchanged.

In `@apps/ade-cli/src/multiProjectRpcServer.ts`:
- Around line 1060-1065: Factor the duplicated runtime metadata object out of
the ade/initialize and runtime/info/machineInfo.get handlers into a shared
helper such as buildRuntimeInfoExtras(). Have both handlers spread the helper
result alongside resolveRuntimeStatus() and resolveRuntimeEnvInfo(), preserving
the existing minCompatibleProtocol, protocolVersion, multiProject, pid, and
uptimeMs values and uptime rounding.

In `@apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts`:
- Around line 1325-1327: Update localRuntimeConnectionPool.activitySummary() to
enforce an explicit short RPC timeout when calling runtime.activitySummary,
using an existing timeout constant or a clearly defined idle-poll timeout from
autoUpdateService.ts. Ensure the timeout is passed through the callSync RPC
options while preserving the RuntimeActivitySummary return behavior.

In `@apps/desktop/src/shared/types/productAnalytics.ts`:
- Around line 13-18: Introduce one shared event-name manifest as the source of
truth for the catalog, using productAnalytics.ts as the canonical type anchor.
Update productAnalyticsPolicy.ts to derive or import its allowlist from that
manifest, and update scripts/posthog/dashboard-spec.mjs to consume the same
manifest through a compatible generated or shared JSON format; remove the
duplicated hand-typed event lists at all three sites.

In `@scripts/posthog/dashboard-spec.mjs`:
- Around line 510-525: Decide whether UPDATE_AUTO_APPLY_CANCELLED represents a
reliability incident alongside the existing update outcome events in the
reliability-incidents insight. If it should be tracked, add
eventNode(UPDATE_AUTO_APPLY_CANCELLED, ...) to the series; otherwise leave the
chart unchanged and preserve the current intentional exclusion.
🪄 Autofix (Beta)

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: fb1b6f34-db7a-4ef7-ab93-2edc47a3e213

📥 Commits

Reviewing files that changed from the base of the PR and between 780fe5e and 8036cc1.

⛔ Files ignored due to path filters (7)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/desktop-auto-update.md is excluded by !docs/**
  • docs/features/remote-runtime/README.md is excluded by !docs/**
  • docs/features/storage-and-recovery/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/README.md is excluded by !docs/**
  • docs/logging.md is excluded by !docs/**
📒 Files selected for processing (81)
  • apps/account-directory/wrangler.jsonc
  • apps/ade-cli/README.md
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/commands/brainUpdate.ts
  • apps/ade-cli/src/commands/doctor.test.ts
  • apps/ade-cli/src/commands/doctor.ts
  • apps/ade-cli/src/multiProjectRpcServer.test.ts
  • apps/ade-cli/src/multiProjectRpcServer.ts
  • apps/ade-cli/src/serviceManager/common.test.ts
  • apps/ade-cli/src/serviceManager/common.ts
  • apps/ade-cli/src/serviceManager/index.ts
  • apps/ade-cli/src/serviceManager/installLaunchd.ts
  • apps/ade-cli/src/services/account/accountAuthService.test.ts
  • apps/ade-cli/src/services/account/accountAuthService.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.test.ts
  • apps/ade-cli/src/services/account/accountMachinePublisherService.ts
  • apps/ade-cli/src/services/personalChats/personalChatScope.ts
  • apps/ade-cli/src/services/projects/projectScope.ts
  • apps/ade-cli/src/services/runtime/brainFreshnessMonitor.test.ts
  • apps/ade-cli/src/services/runtime/brainFreshnessMonitor.ts
  • apps/ade-cli/src/services/runtime/brainLogger.test.ts
  • apps/ade-cli/src/services/runtime/brainLogger.ts
  • apps/ade-cli/src/services/runtime/brainLoopWatchdog.test.ts
  • apps/ade-cli/src/services/runtime/brainLoopWatchdog.ts
  • apps/ade-cli/src/services/runtime/runtimeBuildIdentity.ts
  • apps/ade-cli/src/services/sync/abortSignal.ts
  • apps/ade-cli/src/services/sync/sharedSyncListener.ts
  • apps/ade-cli/src/services/sync/syncHostService.test.ts
  • apps/ade-cli/src/services/sync/syncHostService.ts
  • apps/ade-cli/src/services/sync/syncHostSingleton.ts
  • apps/ade-cli/src/services/sync/syncLoopbackCollision.test.ts
  • apps/ade-cli/src/services/sync/syncPairingConnectInfo.ts
  • apps/ade-cli/src/services/sync/syncProtocol.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.test.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/ade-cli/src/services/sync/syncService.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/analytics/productAnalyticsPolicy.ts
  • apps/desktop/src/main/services/analytics/productAnalyticsService.test.ts
  • apps/desktop/src/main/services/github/adeReleaseFeed.ts
  • apps/desktop/src/main/services/github/githubService.test.ts
  • apps/desktop/src/main/services/github/githubService.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.test.ts
  • apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts
  • apps/desktop/src/main/services/logging/logger.ts
  • apps/desktop/src/main/services/remoteRuntime/syncPairedMachineStore.test.ts
  • apps/desktop/src/main/services/remoteRuntime/syncPairedMachineStore.ts
  • apps/desktop/src/main/services/updates/autoUpdateService.test.ts
  • apps/desktop/src/main/services/updates/autoUpdateService.ts
  • apps/desktop/src/main/services/updates/autoUpdateVersions.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/app/AppShell.tsx
  • apps/desktop/src/renderer/components/app/AutoUpdateBanner.test.tsx
  • apps/desktop/src/renderer/components/app/AutoUpdateBanner.tsx
  • apps/desktop/src/renderer/components/app/AutoUpdateControl.test.tsx
  • apps/desktop/src/renderer/components/app/AutoUpdateControl.tsx
  • apps/desktop/src/renderer/components/app/BrainRecoveryNotice.test.ts
  • apps/desktop/src/renderer/components/app/BrainRecoveryNotice.tsx
  • apps/desktop/src/renderer/components/app/useAutoUpdateSnapshot.ts
  • apps/desktop/src/renderer/components/remoteTargets/RemoteTargetList.tsx
  • apps/desktop/src/renderer/components/remoteTargets/remoteMachineModel.test.ts
  • apps/desktop/src/renderer/components/remoteTargets/remoteMachineModel.ts
  • apps/desktop/src/renderer/components/settings/AboutSection.test.ts
  • apps/desktop/src/renderer/components/settings/AboutSection.tsx
  • apps/desktop/src/renderer/webclient/adapter/app.ts
  • apps/desktop/src/renderer/webclient/adapter/index.ts
  • apps/desktop/src/shared/adeRuntimeProtocol.ts
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/sync/adoptChannelCrypto.test.ts
  • apps/desktop/src/shared/sync/adoptChannelCrypto.ts
  • apps/desktop/src/shared/types/core.ts
  • apps/desktop/src/shared/types/productAnalytics.ts
  • apps/desktop/src/shared/types/sync.ts
  • scripts/posthog/dashboard-spec.mjs
  • scripts/posthog/provision.test.mjs

Comment thread apps/desktop/src/main/services/github/adeReleaseFeed.ts
Comment on lines +1039 to +1080
async function abortInstall(
reason: AutoUpdateInstallAbortReason,
readySnapshot: AutoUpdateSnapshot,
): Promise<false> {
clearQuitDeadline();
installQuitArmed = false;
clearPendingInstallUpdate();
resetAutoApplyTracking(true);
try {
await rollbackQuitAndInstall?.(reason);
} catch (error) {
logger.error("autoUpdate.install_rollback_failed", {
reason,
message: formatErrorMessage(error),
});
}
logger.warn("autoUpdate.install_aborted", {
reason,
version: readySnapshot.version,
});
productAnalyticsService?.captureInternal({
event: "ade_update_install_aborted",
surface: "desktop",
properties: { reason },
});
patchSnapshot({
...readySnapshot,
status: "ready",
latestKnownVersion: snapshot.latestKnownVersion ?? readySnapshot.latestKnownVersion,
progressPercent: 100,
bytesPerSecond: null,
transferredBytes: null,
totalBytes: null,
error: null,
errorDetails: null,
parked: { reason, at: nowMs() },
autoApplyPending: null,
});
installReadySnapshot = null;
scheduleActivityCheck(0);
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the relevant service and surrounding idle/suppression logic.
WD="$(pwd)"
echo "PWD=$WD"
fd -a 'autoUpdateService\.ts$' . || true

FILE="$(fd 'autoUpdateService\.ts$' . | head -n 1)"
if [ -n "${FILE:-}" ]; then
  echo "FILE=$FILE"
  wc -l "$FILE"
  sed -n '1,120p' "$FILE"
  echo "-------------- lines 960-1120 --------------"
  sed -n '960,1120p' "$FILE"
  echo "-------------- scheduleActivityCheck/autoApplySuppressedUntil/refresh/handoff usages --------------"
  rg -n 'scheduleActivityCheck|autoApplySuppressedUntil|autoApplyIdleMs|autoApply.*Suppressed|refresh_failed|handoff_failed|roll|InstallAbortReason|pause|cancel|abortInstall|parked|quitAndInstall' "$FILE"
fi

Repository: arul28/ADE

Length of output: 12981


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="./apps/desktop/src/main/services/updates/autoUpdateService.ts"

echo "-------------- lines 1030-1225 --------------"
sed -n '1030,1225p' "$FILE"

echo "-------------- focused occurrences with context --------------"
python3 - <<'PY'
from pathlib import Path
p = Path('./apps/desktop/src/main/services/updates/autoUpdateService.ts')
lines = p.read_text().splitlines()
targets = [
    'function resetAutoApplyTracking',
    'function clearPendingAutoApply',
    'function scheduleActivityCheck',
    'async function checkAutoApplyActivity',
    'async function abortInstall',
    'function cancelAutoApply',
    '"refresh_failed"',
    '"handoff_failed"',
    '"install_preflight_failed"',
    '"prepare_timeout"',
    '"prepare_failed"',
    '"cancelled"',
]
for t in targets:
    print(f"## {t}")
    for i,l in enumerate(lines, start=1):
        if t in l:
            start=max(1,i-8); end=min(len(lines),i+8)
            for n in range(start,end+1):
                print(f"{n}:{lines[n-1]}")
            print()
PY

Repository: arul28/ADE

Length of output: 15879


Suppress idle auto-apply after parked install aborts.

When the install abort is due to a failed refresh/handoff/preflight/timeout, abortInstall leaves the update as ready with parked but resets auto-apply tracking and schedules the next activity check immediately. Repeated failures will re-enter the idle countdown every autoApplyIdleMs and retry quitAndInstall until the native quit succeeds. Seed autoApplySuppressedUntil on parked aborts for refresh/handoff/setup failures, and clear it on explicit user cancel instead of leaving suppressions to that path alone.

🤖 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 `@apps/desktop/src/main/services/updates/autoUpdateService.ts` around lines
1039 - 1080, Update abortInstall to seed autoApplySuppressedUntil when the
parked abort reason represents a refresh, handoff, preflight, or timeout/setup
failure, preventing idle auto-apply from restarting during the suppression
window. Preserve normal ready-state cleanup for other aborts, and explicitly
clear the suppression timestamp for user-initiated cancellation.

…change, durable env single-flight

Follow-ups to #889 from the final review round: awaited termination/handover
timers stay referenced so a standalone CLI can't exit mid-repair; the session
token exchange runs on the service-owned shared signal as intended; the env
refresh single-flight is released by the shared exchange settling, not by an
aborting caller.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@arul28
arul28 force-pushed the ade/start-skill-both-macbook-mac-01881577 branch from 8036cc1 to 1ea6038 Compare July 24, 2026 03:30
@arul28
arul28 merged commit 4fa1b26 into main Jul 24, 2026
34 checks passed
@arul28
arul28 deleted the ade/start-skill-both-macbook-mac-01881577 branch July 24, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant