Skip to main content

Issue notification and human-task CI regression

Read synchronization when opening an Issue from another entry​

Once Issue activity is visible, the existing POST /v1/loop-items/{id}/read updates the activity cursor and the reader's associated notifications in one transaction. Notifications match by payload itemId or issueId. Other Issues, other recipients, unrelated notifications and existing read timestamps remain unchanged. Reopening previously read content also acknowledges notifications that arrived later. Failed reads preserve the count; successful responses refresh the notification center immediately.

The existing CI checkpoint collaboration-issue-comment-notification runs both its original navigation scenario and the independent issue-notification-read scenario. The new scenario creates three already-read Issues and unread notices through the real Backend, then opens them through a system notification, a deep link and a board card. It asserts persisted reads and badge counts from 3 to 0 without manual refresh, retaining each unrelated notice until its Issue opens. The shared runner cleans up the isolated Electron and database environment. Each Issue deep link carries a fresh open request through the existing focusRequest. Reusing an open drawer acknowledges later notifications while retaining activity scroll progress. The scenario also sends another notice while the drawer remains open, reopens the same Issue through a system notification, and asserts that the badge clears again.

Focused tests additionally cover repeated reads, recipient isolation, unrelated notifications, failed reads without refresh and revisiting already-read content. Activity must load and become visible before acknowledging a read.

2026-10-27: the isolated Electron issue-notification-read checkpoint passed all three entry paths and later notifications for the same open drawer. Four Backend read API regressions, 37 notification/API tests, 146 activity/routing tests, 19 shared scrolling tests and four checkpoint contract tests passed. Fixtures retain project IDs as strings to avoid JavaScript Number precision loss.

The same CI run exposed a shared desktop artifact build waiting for a nonexistent Rust image: its consumer omitted the producer's backend-rs/examples/** from the source digest. Desktop CI and cache warmup now use the producer's source inputs, with a contract check covering all three definitions instead of increasing waits.

Evidence and fix boundaries​

PR #3763 at f124f3d2e failed desktop Core shards 12 and 15:

  • The project-assignment-notification failure snapshot contains the bound Task entry below the viewport. The visible-element click command does not scroll. The scenario must check disclosure state, wait for the row, and scroll before clicking, while retaining its bound-model assertion.
  • The first deep link in collaboration-issue-comment-notification highlights correctly. After reload, clicking the same notification does not highlight again: the unchanged route issues no new focus request, and the view deduplicates by comment ID indefinitely.

Each comment navigation receives an internal focusRequest through the existing project route. Tab matching ignores that request identifier to reuse the existing tab. Each request scrolls and highlights once; background message updates do not rehighlight. A rapid repeat ends the old animation and starts a new one on the next frame. No user-entered fields, model/device routing changes, or human submission permission changes are introduced.

QA plan​

Observing the transient highlight​

PR #3947 Core shard 8 read animation-name=none after waiting for the comment to settle. The scenario waited for the detail and comment to remain stable for 400 ms each before querying a two-second animation. A busy runner can consume that observation window. The scenario now reuses renderer frame sampling before navigation to retain the exact comment selector's animationName, then checks the record after landing. It does not extend the animation or wait budgets. Each navigation rejects an existing highlight and retains its own frame evidence. A missing target animation, another comment's animation, failed navigation, or a highlight beyond the original eight-second budget still fails. The six-second landing budget, reload, link opening, and persisted-read checks remain intact; product highlight behavior is unchanged.

Focused tests cover expired animation records, exact comment ownership, and failure cleanup. Real Electron continues to run the existing collaboration-issue-comment-notification checkpoint in Core CI.

Local push-gate resource isolation​

Memory-constrained hosts can set WEWORK_PRE_PUSH_RENDERER_SHARD_CONCURRENCY=1 to run the original complete 1/2 and 2/2 renderer shards serially. The default still runs both concurrently; WEWORK_PRE_PUSH_TEST_WORKERS continues to control workers per shard. All files, timeouts, and failure propagation remain intact, and a failed first shard still runs the second. Invalid concurrency values explicitly block the push. Gate regressions cover non-overlap, complete coverage, and failure propagation.

The visible activity cursor unit test waits for loaded comments and drives the real scrolling hook with controlled animation frames. It no longer depends on the host scheduling requestAnimationFrame promptly. No read may occur before the frame; afterward only visible sequence 2 may be acknowledged, never offscreen sequence 3, with the original parent callback checks retained. Product scrolling and presentation behavior remain unchanged.

Environment: isolated Electron with real Backend, Socket.IO and devices; only model services use the scenario's test service. Focused local Vitest checks run before submission; existing GitHub Core shards provide desktop validation. Do not drive a personal window, rerun to obtain green, increase timeouts, or skip assertions.

PreconditionsActionExpected result
Human Issue has a bound remote AI-draft TaskChange the new-chat default; expand, scroll to and reopen the bound TaskRetain the bound model; human submission remains required
First comment notificationOpen its deep linkScroll and highlight within existing budgets; other comments remain unhighlighted
Reload restored the same comment; previous flash endedClick the same inbox notificationReuse the tab, issue a fresh focus, highlight again and persist read state
Flash still activeRefocus the same comment quicklyRestart the animation rather than inherit its remaining duration
Focus request unchangedBackground messages or rerenderNo repeated scrolling or highlighting
Comment not loaded, or focus clearedLoad it; leave and refocusHighlight after loading; refocusing is allowed
Animation frame pendingUnmountClean up animation frames and timers

Existing CI scenarios retain real remote-device, binding, delivery, human submission/review and read-persistence assertions. Keep failure snapshots/logs and inspect success screenshots. Fixtures use isolated users, projects and run directories, cleaned up by the desktop runner.

Verification record​

2026-10-09: new repeated-notification routing and highlight assertions failed before the fix and passed afterward. Seven focused files with 177 tests passed, covering notification routing, comment focus, the Issue editor and human-task drawers. ESLint, Prettier, TypeScript and both scenario syntax checks passed. Local results do not establish real remote-device or desktop E2E success; final verification belongs to CI on the fix commit.

After the push, main introduced Issue archiving and conflicted in the properties menu. The merge retains the archive label/callback and outside-click dismissal, with a regression assertion covering both. Revalidate shared archive components, the desktop editor and Backend endpoints after the merge.

Main subsequently unified Issue execution state and replies. The merge must keep both the agent Team/model binding and the execution thread, workspace and Issue session context, including bindings with no selected model. Focused tests caught a missing database argument in the successful continuation status push to to_view; it has been corrected. Verify original-session continuation, queued replies, reassignment and manually bound agent models. The panel-reopening unit test establishes its active project directly, reuses its interaction device and asserts that the old panel closed before reopening. It retains the late-address isolation assertion without increasing the timeout.

Reassignment to the same human after unassignment​

Core shard 12 at f5bbaab0c failed after human acceptance and reassignment: human_work.state remained accepted instead of none for the new assignment. The legacy PATCH endpoint cleared the assignee field without revoking its assignment activity, so assigning the same human again was incorrectly deduplicated. Direct human unassignment now reuses the existing event removal service in the same version-checked transaction as the assignee update.

Regression coverage includes reassignment to the same or another human on in-review and completed Issues. A new event ID preserves the Issue status until the human explicitly starts work. Repeated assignment without unassignment stays idempotent; version conflicts preserve assignments; workflow-step assignments are not removed. Existing review records, desktop E2E assertions and timeouts remain unchanged.

Main-branch merge regression on 2026-10-10​

Keep main's inline Issue title/description editing, attachment previews and personal-task workspace selection alongside human processing, AI drafts, tag editing and outside-click dismissal. Ordinary personal tasks do not inherit an agent's project environment; human AI assistance still uses the latest saved project device/directory and human assignment binding. Comment notifications use the same internal focusRequest parameter throughout navigation. Timestamp normalization uses the configurable database timezone without shifting SQLite or already timezone-aware values twice.

Project creation/view switching and member, bot and group assignment component tests are separate scenarios, each establishing its own prerequisites and retaining the original assertions without extra timeouts or retries. Verify shared components, desktop editors/drawers/notifications, Web details and database timestamps after merging. Focused unit tests and type checks are not real remote-device or desktop E2E acceptance.

Issue edit conflicts during execution​

PR #3869 Core shard 9 failed collaboration-local-agent-dispatch: reopening the Issue showed its original title. Runtime logs show that todos.update returned version_conflict while execution advanced the Issue version. A displayed draft value does not establish that the save succeeded.

Detail saves submit only edited fields. On a version conflict, read the latest Issue and submit once with its version only if those fields were not changed by another editor. Same-field conflicts, unrelated request errors, and a second version conflict remain failures. Unedited execution status, priority, and other fields cannot be overwritten by the old draft. Assignment-only changes skip the redundant detail write and assign against the current version.

Focused regressions cover title edits concurrent with execution status changes, same-field conflicts, network failures, repeated conflicts, unchanged fields, and assignments. Existing desktop E2E save/reopen title assertions remain intact; CI on the fix commit supplies real integration verification.

MySQL Concurrency for First Member Activities​

A member runtime event may arrive before its activity exists. Looking up a missing runtime activity must not use FOR UPDATE on the Runtime secondary index: InnoDB gap locks can conflict with other members’ first inserts. Find an existing activity’s primary key first, then lock that key and refresh its contents. This avoids locking absent members while retaining serialization for existing activities.

backend/tests/integration/runtime_activity_mysql.py uses synchronization barriers against real MySQL at REPEATABLE READ to reproduce independent first inserts and verify that concurrent updates to one activity retain both results. The first platform E2E shard invokes this check. The existing two-round collaboration E2E still verifies parallel members, complete results, and fresh manager tasks.