When a Gitea comment approves a plan, the handler runs on the worker while the poller's thread waits in worker.call. Approving the architecture plans the milestone and posts it, and _post_plan_to_board calls _watch("plan", …). That replaces the poller that delivered the comment: _unwatch → CommentPoller.stop() joins that poller's thread, which is itself blocked waiting on this job. The join times out after interval_s + 5 (25 s by default) and work carries on, so nothing breaks, but a Gitea approval stalls the agent for ~25 s.
Options:
keep the same poller and move it to the new revision (update its cursor/priming) instead of replacing it;
or, in stop(), skip the join when called from the poller's own delivery path, so the thread exits by itself after the callback returns.
Test: approve a plan through a Gitea comment with a real threaded poller and assert the handler returns well under the join timeout.
Noticed while doing #68.
When a Gitea comment approves a plan, the handler runs on the worker while the poller's thread waits in `worker.call`. Approving the architecture plans the milestone and posts it, and `_post_plan_to_board` calls `_watch("plan", …)`. That replaces the poller that delivered the comment: `_unwatch` → `CommentPoller.stop()` joins that poller's thread, which is itself blocked waiting on this job. The join times out after `interval_s + 5` (25 s by default) and work carries on, so nothing breaks, but a Gitea approval stalls the agent for ~25 s.
**Options:**
- keep the same poller and move it to the new revision (update its cursor/priming) instead of replacing it;
- or, in `stop()`, skip the join when called from the poller's own delivery path, so the thread exits by itself after the callback returns.
**Test:** approve a plan through a Gitea comment with a real threaded poller and assert the handler returns well under the join timeout.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Noticed while doing #68.
When a Gitea comment approves a plan, the handler runs on the worker while the poller's thread waits in
worker.call. Approving the architecture plans the milestone and posts it, and_post_plan_to_boardcalls_watch("plan", …). That replaces the poller that delivered the comment:_unwatch→CommentPoller.stop()joins that poller's thread, which is itself blocked waiting on this job. The join times out afterinterval_s + 5(25 s by default) and work carries on, so nothing breaks, but a Gitea approval stalls the agent for ~25 s.Options:
stop(), skip the join when called from the poller's own delivery path, so the thread exits by itself after the callback returns.Test: approve a plan through a Gitea comment with a real threaded poller and assert the handler returns well under the join timeout.
🤖 Generated with Claude Code
https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE