Skip to content

fix(monitor): GUI scheduled scan から自律起動を駆動する - #3517

Merged
akiojin merged 9 commits into
developfrom
work/issue-3505
Aug 11, 2026
Merged

akiojin merged 9 commits into
developfrom
work/issue-3505

Conversation

@akiojin

@akiojin akiojin commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • GUI-only topology の scheduled tick を authority-fenced background worker へ接続し、scan から claim、pending delivery、autonomous launch まで進めます。
  • daemon authority、無効化競合、PM periodic wake、remote failure を lifecycle 全体で fail-closed かつ観測可能にします。

Changes

  • crates/gwt/src/app_runtime/: project-scoped single-flight worker、typed completion、fresh prefs rebase、local claim effect driver、queue/active/needs_human wake を追加しました。
  • crates/gwt/src/issue_monitor.rscrates/gwt/src/cli/daemon/server.rs: GUI fallback lease と daemon startup retry を同じ authority lock 上で実装しました。
  • free lifetime lock に残った stale v2 fence は authority epoch を revoke して回収し、legacy fence は fail-closed を維持します。
  • Windows compatibility claim driver も scheduled worker と同じ fallback lease を取得し、remote mutation を直列化します。
  • crates/gwt-github/src/issue_auto_claim.rs: runtime の trait-object client から claim mutation を実行できるよう generic 境界を拡張しました。
  • .github/workflows/test.yml: Windows native で no-daemon scheduled launch、disabled cleanup、local driver、lease 契約を明示実行します。
  • crates/gwt/src/app_runtime/tests.rs: no-daemon progress、live fence zero mutation、commit-time race、single-flight、disabled cleanup、completion wake、failure visibility、compatibility driver競合の回帰 matrix を追加しました。

Testing

  • cargo fmt --all -- --check — PASS
  • cargo clippy --all-targets --all-features -- -D warnings — PASS
  • cargo test -p gwt-core -p gwt --all-features -- --test-threads=1 — PASS
  • cargo build -p gwt --bin gwt --bin gwtd — PASS
  • bash scripts/check-frontend-bundle.sh — PASS
  • bash scripts/run-frontend-unit-tests.sh — 1197 PASS
  • bash scripts/run-frontend-smoke-tests.sh — 30 PASS
  • bash scripts/run-visual-tests.sh — 214 PASS / 82 skipped
  • headed Issue Monitor live E2E — 1 PASS
  • authority review matrix — fallback lifecycle 5 PASS / scheduled 13 PASS / local driver 3 PASS
  • Final Verification Run Record: vrr-e66ca093b65642fb83dc5b6203c49a69

PR Readiness

  • State: Ready for review
  • Releaseable slice: yes — daemon 不在時の autonomous launch を完結させ、daemon 併存時は排他します
  • Known blockers: None
  • Remaining acceptance: None
  • User Verification Result: n/a — backend scheduler/authority correctionでUI表示変更なし

Closing Issues

Related Issues / Links

Checklist

Context

Risk / Impact

@akiojin
akiojin enabled auto-merge August 11, 2026 05:57
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds asynchronous, authority-fenced Issue Monitor scheduled scans. It adds local fallback leasing, daemon startup retry handling, durable result rebasing, PM wake integration, completion events, shared claim execution, and Windows contract tests.

Changes

Issue Monitor scheduling

Layer / File(s) Summary
Authority fallback and daemon startup
crates/gwt/src/issue_monitor.rs, crates/gwt/src/cli/daemon/server.rs, crates/gwt/src/lib.rs
Fallback leases recover stale fences. Daemon startup retries temporary fallback-lock contention before readiness.
Authority-fenced effect execution
crates/gwt-github/src/issue_auto_claim.rs, crates/gwt/src/app_runtime/mod.rs
Claim helpers accept dynamically sized clients. Effect preparation and result commits use fallible authority-fenced persistence.
Scheduled workers and event flow
crates/gwt/src/app_runtime/mod.rs, crates/gwt/src/app_runtime/pm.rs, crates/gwt/src/main.rs
Scheduled scans use single-flight blocking workers, authority checks, durable rebasing, completion events, pending launch processing, and monitor-aware PM wakes.
Regression tests and Windows validation
crates/gwt/src/app_runtime/tests.rs, crates/gwt/src/cli/daemon/server.rs, .github/workflows/test.yml, .gwt/work/events.jsonl
Tests cover authority races, failures, cleanup, launches, wakes, and daemon coordination. Windows CI runs scheduled-driver contract tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ScheduledTick
  participant AppRuntime
  participant IssueMonitorWorker
  participant GitHubIssueClient
  participant UserEventLoop
  ScheduledTick->>AppRuntime: request scheduled scan
  AppRuntime->>IssueMonitorWorker: start single-flight worker
  IssueMonitorWorker->>GitHubIssueClient: scan candidates and execute effects
  GitHubIssueClient-->>IssueMonitorWorker: return scan and mutation results
  IssueMonitorWorker-->>UserEventLoop: emit completion event
  UserEventLoop->>AppRuntime: process results and PM wake events
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: driving autonomous launches from GUI scheduled scans.
Linked Issues check ✅ Passed The changes implement the linked issue requirements for scheduled scans, authority fencing, single-flight workers, autonomous launches, wake rearming, and failure visibility [#3505].
Out of Scope Changes check ✅ Passed The code changes support the linked issue through authority coordination, fallback leases, daemon retry handling, trait-object support, and targeted tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ 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 work/issue-3505

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.

@akiojin
akiojin disabled auto-merge August 11, 2026 05:58

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 354fb5f772

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/gwt/src/issue_monitor.rs
Comment thread crates/gwt/src/app_runtime/mod.rs
@akiojin
akiojin enabled auto-merge August 11, 2026 07:40
@akiojin
akiojin merged commit d35f97d into develop Aug 11, 2026
12 of 13 checks passed

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/gwt/src/main.rs (1)

7808-7821: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

scheduler 起動失敗時に正常起動を継続しないでください。

この thread は GUI-only topology の scheduled scan を開始する主要な起点です。thread::spawn が失敗しても GUI を継続すると、アプリは正常起動に見えますが、scheduled scan と autonomous launch は実行されません。

起動を失敗させるか、限定回数の再試行と degraded 状態の通知を実装してください。

最小修正案
         {
             tracing::error!(%error, "failed to start Issue Monitor scheduled tick thread");
+            return Err(error);
         }
🤖 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 `@crates/gwt/src/main.rs` around lines 7808 - 7821, Update the scheduled-tick
thread startup around IssueMonitorScheduledTick so a std::thread::Builder::spawn
failure prevents normal GUI startup from continuing. Propagate the spawn error
through the surrounding initialization path and return/abort startup, or
implement bounded retries with an explicit degraded-state notification; do not
merely log the error and continue.
🧹 Nitpick comments (9)
crates/gwt/src/app_runtime/tests.rs (2)

3000-3038: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Consider a longer deadline for Windows CI.

The helper waits at most 5 seconds. The scheduled worker in the new Windows job spawns a fake gh process and performs git/prefs I/O. Process spawn on windows-latest is slow, so this bound can produce flaky failures. A 30-second deadline keeps the failure message useful and removes the timing risk.

♻️ Proposed change
-    let deadline = Instant::now() + Duration::from_secs(5);
+    let deadline = Instant::now() + Duration::from_secs(30);
🤖 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 `@crates/gwt/src/app_runtime/tests.rs` around lines 3000 - 3038, Increase the
timeout in wait_for_scheduled_scan_completion from 5 seconds to 30 seconds so
scheduled scan completion remains reliable on slower Windows CI while preserving
the existing polling and failure behavior.

43597-43603: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Clear the global scan hook when the test ends.

set_scheduled_scan_after_lease_before_commit_test_hook stores the closure in a process-global slot and asserts that the slot is empty (crates/gwt/src/app_runtime/mod.rs lines 962-967). The worker consumes the hook only when it reaches the commit point. If the worker fails earlier, the hook stays installed for the rest of the test binary process, and the next test that installs a hook panics on the assert. Add a scope guard that clears the slot on drop, so the contract stays safe when a second test starts using this hook.

🤖 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 `@crates/gwt/src/app_runtime/tests.rs` around lines 43597 - 43603, Add a scope
guard around the test’s use of
set_scheduled_scan_after_lease_before_commit_test_hook that clears the global
hook slot on drop, including when the worker exits before consuming it. Ensure
the guard is held for the test’s full execution and uses the existing
hook-clearing mechanism rather than changing the worker behavior.
.github/workflows/test.yml (1)

110-114: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make contract filters fail when no tests match.

The current filters match tests. The three named filters match one test each, app_runtime_local_driver_ matches three binary tests, and local_fallback_lease matches three library tests. The --lib target is correct.

If these commands must detect renames, add --exact to the three single-test commands. Replace the prefix filters with explicit names or assert the expected match count.

🤖 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 @.github/workflows/test.yml around lines 110 - 114, Update the targeted cargo
test commands so contract filters fail when tests are renamed or removed: add
--exact to the three single-test filters, and replace app_runtime_local_driver_
and local_fallback_lease with explicit test names or otherwise validate their
expected match counts while preserving the --lib target.
crates/gwt/src/app_runtime/mod.rs (3)

1653-1669: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy lift

Replace the string-matched error classification with a typed signal.

Line 1658 selects between record_scan_error and record_launch_auth_required by testing whether the error message contains "deadline". The same pattern exists in the pre-existing Windows driver at line 3921, but this PR makes it part of the primary GUI-only scheduled path.

The failure mode is asymmetric. A deadline error whose text stops containing "deadline" is recorded as launch_auth_required, which is a sticky state the operator must clear, instead of a transient scan error that self-heals on the next tick.

Return a typed error from execute_local_issue_monitor_claim_effects — for example an enum distinguishing DeadlineExpired from AuthUnavailable — and match on it at both call sites.

🤖 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 `@crates/gwt/src/app_runtime/mod.rs` around lines 1653 - 1669, Replace the
string-based `"deadline"` check in execute_local_issue_monitor_claim_effects and
its callers with a typed error enum distinguishing DeadlineExpired from
AuthUnavailable. Return the appropriate variant from
execute_local_issue_monitor_claim_effects, then match on that enum at both the
GUI scheduled path and the existing Windows driver call site, routing
DeadlineExpired to record_scan_error and AuthUnavailable to
record_launch_auth_required.

1420-1463: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename the shadowed owner binding.

The closure parameter list binds the repo owner as owner. The AcquireClaim arms then destructure a payload field also named owner, which is the claim owner. Inside those arms owner refers to the claim owner.

The current code is correct because issue_client_factory(owner, repo) is evaluated at line 1420, before the match, so it receives the repo owner. The shadowing is still a hazard: moving the factory call into an arm would silently pass the claim owner as the repo owner, and the two values are both plain &str.

Rename the destructured field binding to make the distinction explicit.

♻️ Proposed refactor
                 gwt::IssueMonitorEffectPayload::AcquireClaim {
                     issue_number,
                     claim_id,
-                    owner,
+                    owner: claim_owner,
                     heartbeat_at,
                     expires_at,
                     launched_work_id,
                 } if authority_current => {
@@
                         ClaimComment {
                             comment_id: None,
                             claim_id: claim_id.clone(),
-                            owner: owner.clone(),
+                            owner: claim_owner.clone(),
                             issue_number: *issue_number,

Apply the same rename to the revoke arm and the ReleaseClaim arm.

🤖 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 `@crates/gwt/src/app_runtime/mod.rs` around lines 1420 - 1463, Rename the
`AcquireClaim` payload’s destructured `owner` binding to a distinct claim-owner
name in both match arms, and update the corresponding `ClaimComment` and
`release_claim_mutation` arguments. Apply the same rename in the revoke and
`ReleaseClaim` arms while keeping the outer repository owner binding used by
`issue_client_factory` unchanged.

1519-1522: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Distinguish "monitor disabled" from "deferred to a live daemon".

This early return reports ScheduledIssueMonitorScanOutcome::DeferredToLiveDaemon when the monitor is disabled and no claim cleanup is pending. No daemon is involved in that decision.

The completion handler at line 4042 happens to do the right thing for both cases — it re-arms the PM periodic wake — so behavior is correct today. The name misdescribes the cause, which will mislead the next reader of a log or a test assertion.

Add a third variant, for example NothingToDo, and map it to the same completion behavior.

🤖 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 `@crates/gwt/src/app_runtime/mod.rs` around lines 1519 - 1522, Add a distinct
ScheduledIssueMonitorScanOutcome variant such as NothingToDo for the
disabled-monitor/no-cleanup path in the scheduled scan logic, replacing the
misleading DeferredToLiveDaemon return. Update the completion handler around its
existing outcome match to treat NothingToDo identically to DeferredToLiveDaemon,
preserving the PM periodic wake re-arm behavior.
crates/gwt/src/cli/daemon/server.rs (2)

358-367: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify the terminal-state destructuring.

The retry loop already guarantees authority_retry_pending == false at this point. The let ... else with a false literal pattern plus unreachable!() encodes that invariant in a refutable pattern, which is harder to read than the invariant it protects.

Use an irrefutable destructure and a debug_assert!.

♻️ Proposed refactor
         let LoadedDaemonIssueMonitorState {
             mut monitor,
             recovery_blocked,
-            authority_retry_pending: false,
+            authority_retry_pending,
             authority_fence,
             authority_lease,
-        } = loaded
-        else {
-            unreachable!("authority retry loop exits only with a terminal load state")
-        };
+        } = loaded;
+        debug_assert!(
+            !authority_retry_pending,
+            "authority retry loop exits only with a terminal load state"
+        );
🤖 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 `@crates/gwt/src/cli/daemon/server.rs` around lines 358 - 367, Update the
terminal-state destructuring of LoadedDaemonIssueMonitorState to bind
authority_retry_pending instead of matching it against false, making the
destructure irrefutable and removing the unreachable! branch. Immediately follow
it with a debug_assert! that authority_retry_pending is false, while preserving
the existing monitor, recovery_blocked, authority_fence, and authority_lease
bindings.

6608-6671: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Isolate the worker test from process-global environment state.

This test spawns the real Issue Monitor worker, which starts a scan that reads the ambient GWT home and PATH. Neighboring worker tests in this module guard that state — for example worker_shutdown_after_ready_preserves_new_corrupt_bytes takes crate::env_test_lock() and installs ScopedGwtHome. Without those guards a parallel test that mutates HOME, GWT_HOME, or PATH can make this test flaky, and the first scan invokes whatever gh binary is on the ambient PATH.

Add the same environment guards used by the other worker tests.

♻️ Proposed fix
     #[tokio::test]
+    #[allow(clippy::await_holding_lock)] // global environment must stay isolated for the worker lifetime
     async fn worker_stays_starting_until_the_local_fallback_lease_is_released() {
+        let _env_lock = crate::env_test_lock()
+            .lock()
+            .unwrap_or_else(std::sync::PoisonError::into_inner);
         let temp = TempDir::new().expect("tempdir");
+        let home = temp.path().join("home");
+        fs::create_dir_all(&home).expect("create gwt home");
+        let _home = ScopedGwtHome::set(&home);
         let repo = temp.path().join("repo");
🤖 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 `@crates/gwt/src/cli/daemon/server.rs` around lines 6608 - 6671, Update
worker_stays_starting_until_the_local_fallback_lease_is_released to acquire
crate::env_test_lock() and install the same ScopedGwtHome and PATH isolation
used by neighboring worker tests, especially
worker_shutdown_after_ready_preserves_new_corrupt_bytes. Keep these guards
active for the entire real-worker lifetime so its initial scan cannot observe
concurrent process-global environment changes.
crates/gwt/src/issue_monitor.rs (1)

9257-9328: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a fallback-lease test for the legacy fence arm.

The three tests cover Missing, live-lock Active, and stale v2 Active. They do not cover the LegacyShutdownRevoke | Active(_) arm of try_acquire_issue_monitor_local_fallback_lease. That arm is the fail-closed guard against a legacy daemon. Add a test that seeds a v1 fence and asserts WouldBlock, an unchanged fence file, and an unchanged effect_authority_epoch.

The repository targets 90%+ coverage across unit, integration, and E2E tests, so this branch should be pinned. As per coding guidelines, "gwt プロジェクトでは単体テスト、結合テスト、E2E テストを含む全体のテストカバレッジを 90% 以上で維持する".

🤖 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 `@crates/gwt/src/issue_monitor.rs` around lines 9257 - 9328, Add a unit test
alongside the existing local fallback lease tests that seeds a legacy v1 fence,
invokes try_acquire_issue_monitor_local_fallback_lease, and asserts it returns
io::ErrorKind::WouldBlock. Capture and compare the fence state/file contents and
effect_authority_epoch before and after the call to verify the fail-closed
LegacyShutdownRevoke | Active(_) path leaves both unchanged.

Source: Coding guidelines

🤖 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 @.github/workflows/test.yml:
- Around line 108-115: Add shell: bash to both multi-line Windows test steps,
including the step running the Issue Monitor scheduled driver contracts and the
preceding step around line 98, so any failed cargo test causes the workflow step
to fail.

In @.gwt/work/events.jsonl:
- Around line 1522-1536: Remove the manually added Issue `#3505` lifecycle rows
from the projection log, especially the entries ending in the premature
kind:"done" event. Do not edit `.gwt/work/events.jsonl` to record progress or
completion; track remaining commit, verification, push, and PR work in Issue
`#3505` and let the runtime emit events after those actions actually occur.

In `@crates/gwt/src/app_runtime/mod.rs`:
- Around line 4057-4068: Update the `latest` preference match in the scheduled
completion flow to call `pm_periodic_wake_events_at` before returning on both
the disabled `Ok(_)` path and the reload-error `Err(error)` path. Preserve the
existing empty-vector and toast responses while ensuring each path re-arms the
periodic wake.
- Around line 1083-1085: Remove the 250 ms ScopedOperationDeadline applied
inside try_rebase_mutate_and_persist_issue_monitor_state_without_authority_fence
so run_scheduled_issue_monitor_scan’s 60-second deadline remains effective for
background scans; preserve the existing DeferredToLiveDaemon handling.

In `@crates/gwt/src/cli/daemon/server.rs`:
- Around line 341-350: Update the retry loop around
load_issue_monitor_state_for_daemon to execute each state reload via
tokio::task::spawn_blocking, awaiting the blocking task before continuing.
Preserve the existing 25 ms delay, shutdown handling, and loaded-state
assignment while ensuring the blocking file and filesystem work does not run on
Tokio worker threads.

---

Outside diff comments:
In `@crates/gwt/src/main.rs`:
- Around line 7808-7821: Update the scheduled-tick thread startup around
IssueMonitorScheduledTick so a std::thread::Builder::spawn failure prevents
normal GUI startup from continuing. Propagate the spawn error through the
surrounding initialization path and return/abort startup, or implement bounded
retries with an explicit degraded-state notification; do not merely log the
error and continue.

---

Nitpick comments:
In @.github/workflows/test.yml:
- Around line 110-114: Update the targeted cargo test commands so contract
filters fail when tests are renamed or removed: add --exact to the three
single-test filters, and replace app_runtime_local_driver_ and
local_fallback_lease with explicit test names or otherwise validate their
expected match counts while preserving the --lib target.

In `@crates/gwt/src/app_runtime/mod.rs`:
- Around line 1653-1669: Replace the string-based `"deadline"` check in
execute_local_issue_monitor_claim_effects and its callers with a typed error
enum distinguishing DeadlineExpired from AuthUnavailable. Return the appropriate
variant from execute_local_issue_monitor_claim_effects, then match on that enum
at both the GUI scheduled path and the existing Windows driver call site,
routing DeadlineExpired to record_scan_error and AuthUnavailable to
record_launch_auth_required.
- Around line 1420-1463: Rename the `AcquireClaim` payload’s destructured
`owner` binding to a distinct claim-owner name in both match arms, and update
the corresponding `ClaimComment` and `release_claim_mutation` arguments. Apply
the same rename in the revoke and `ReleaseClaim` arms while keeping the outer
repository owner binding used by `issue_client_factory` unchanged.
- Around line 1519-1522: Add a distinct ScheduledIssueMonitorScanOutcome variant
such as NothingToDo for the disabled-monitor/no-cleanup path in the scheduled
scan logic, replacing the misleading DeferredToLiveDaemon return. Update the
completion handler around its existing outcome match to treat NothingToDo
identically to DeferredToLiveDaemon, preserving the PM periodic wake re-arm
behavior.

In `@crates/gwt/src/app_runtime/tests.rs`:
- Around line 3000-3038: Increase the timeout in
wait_for_scheduled_scan_completion from 5 seconds to 30 seconds so scheduled
scan completion remains reliable on slower Windows CI while preserving the
existing polling and failure behavior.
- Around line 43597-43603: Add a scope guard around the test’s use of
set_scheduled_scan_after_lease_before_commit_test_hook that clears the global
hook slot on drop, including when the worker exits before consuming it. Ensure
the guard is held for the test’s full execution and uses the existing
hook-clearing mechanism rather than changing the worker behavior.

In `@crates/gwt/src/cli/daemon/server.rs`:
- Around line 358-367: Update the terminal-state destructuring of
LoadedDaemonIssueMonitorState to bind authority_retry_pending instead of
matching it against false, making the destructure irrefutable and removing the
unreachable! branch. Immediately follow it with a debug_assert! that
authority_retry_pending is false, while preserving the existing monitor,
recovery_blocked, authority_fence, and authority_lease bindings.
- Around line 6608-6671: Update
worker_stays_starting_until_the_local_fallback_lease_is_released to acquire
crate::env_test_lock() and install the same ScopedGwtHome and PATH isolation
used by neighboring worker tests, especially
worker_shutdown_after_ready_preserves_new_corrupt_bytes. Keep these guards
active for the entire real-worker lifetime so its initial scan cannot observe
concurrent process-global environment changes.

In `@crates/gwt/src/issue_monitor.rs`:
- Around line 9257-9328: Add a unit test alongside the existing local fallback
lease tests that seeds a legacy v1 fence, invokes
try_acquire_issue_monitor_local_fallback_lease, and asserts it returns
io::ErrorKind::WouldBlock. Capture and compare the fence state/file contents and
effect_authority_epoch before and after the call to verify the fail-closed
LegacyShutdownRevoke | Active(_) path leaves both unchanged.
🪄 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: d197bf20-0b8f-4c02-b4a9-6f7919a94fcf

📥 Commits

Reviewing files that changed from the base of the PR and between 88ae505 and 6559431.

📒 Files selected for processing (10)
  • .github/workflows/test.yml
  • .gwt/work/events.jsonl
  • crates/gwt-github/src/issue_auto_claim.rs
  • crates/gwt/src/app_runtime/mod.rs
  • crates/gwt/src/app_runtime/pm.rs
  • crates/gwt/src/app_runtime/tests.rs
  • crates/gwt/src/cli/daemon/server.rs
  • crates/gwt/src/issue_monitor.rs
  • crates/gwt/src/lib.rs
  • crates/gwt/src/main.rs

Comment thread .github/workflows/test.yml
Comment thread .gwt/work/events.jsonl
Comment thread crates/gwt/src/app_runtime/mod.rs
Comment thread crates/gwt/src/app_runtime/mod.rs
Comment thread crates/gwt/src/cli/daemon/server.rs
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