Skip to content

fix(status): aggregate scoped component names and label zero-worker main thread as main - #3591

Merged
kriszyp merged 2 commits into
mainfrom
fix/status-thread-label-and-main
Oct 29, 2026
Merged

kriszyp merged 2 commits into
mainfrom
fix/status-thread-label-and-main

Conversation

@kriszyp

@kriszyp kriszyp commented Oct 26, 2026 •

Copy link
Copy Markdown
Member
Storybook forest: Dawson snips scoped component tags at their last @ so each lands in its own tree-stump cubby, the blank-quotes cubby is crossed out and the main-thread cubby reads main, while Kris, Bari and the woodland animals watch.

⊙ Problem

  1. Scoped component names (such as @scope/app-a@main) collapse under the empty-string key "" during status aggregation. StatusAggregator.aggregate splits on indexOf('@') instead of lastIndexOf('@'). get_status merges unrelated scoped components under "", and get_components reports { status: 'unknown' }.
  2. In zero-worker mode (threads.count: 0), setMainIsWorker(true) makes getWorkerIndex() return 0 on the main thread, so main-thread component statuses are mislabelled worker-0 instead of main.

🤔 Why a shared parser and isMainThread?

Centralizing key parsing in one helper keeps component grouping, thread-label extraction, and abnormality normalization aligned on the last @. Checking isMainThread from node:worker_threads identifies the main thread directly without changing getWorkerIndex(), which Table.ts relies on for TTL ownership.

💡 Solution

Parse @<threadLabel> suffixes through a shared parseStatusKey helper using lastIndexOf('@'). Check isMainThread in CrossThreadStatusCollector and componentStatusRequestHandler. In zero-worker mode (threads.count: 0), get_components and get_status now report main-thread status timestamps under lastChecked.main (with lastChecked.workers empty). They key main-thread abnormalities as <component>@main instead of <component>@worker-0.

🔧 Changes

✅ Verification

  • Verified all three new unit tests fail against origin/main sources before the fix (36 passing, 3 failing).
  • Rebuilt (npm run build) and ran npx mocha unitTests/components/status/*.test.js unitTests/server/status/*.test.js unitTests/server/itc/*.test.js (246 passing).
  • Ran npm run lint and npm run typecheck.

PR QA: none — surgical status-key parsing and thread-label check covered by unit tests


Author: Gemini (gemini-4-argon-high)

Release target: main — status-correctness fix for the next minor; no patch backport needed
Related PRs: #3439 overlaps, #2155 independent

Origin — the dispatch brief this PR was written from

components/status/crossThread.ts: (1) StatusAggregator.aggregate strips the @ suffix with indexOf('@') while the other two sites use lastIndexOf('@'), so scoped component names (@scope/app-a@main) aggregate under '' / truncated keys; use one shared stripping helper for all three sites. (2) In zero-worker mode (threads.count: 0) main-thread component statuses are labelled worker-0, because getWorkerIndex() (0 on the main thread) is used to pick the 'main' label in crossThread.ts and server/itc/serverHandlers.ts: use an explicit main-thread check. Leave warning/loading ranking to open PR #3439.

Acceptance

Tests: @scope/app-a@main, @scope/app-a.rest@main and @scope/app-b@worker-0 aggregate to their own names with no '' key; with threads.count: 0, main-thread statuses are labelled main. Show each new test failing on origin/main sources (forced rebuild) before the fix.

Dispatch: task harper-status-thread-label-and-main · queued by finding-triage/wave-40 · ran by gemini/gemini-4-argon-high/low · worker kzyp-xps-1

Review-Coverage: authored=claude; ran=cursor-composer,codex,gemini; adjudicated=domain; declined=cursor-grok,muse; rounds=5; full=3 @ 0661aa7

Review-Attention: read ~3m (decisions: physical-thread-identity-for-main-label, test-seam-parameter) @ 0661aa7

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the cross-thread status collection and aggregation logic to correctly handle scoped component names (e.g., @scope/app-a) and to ensure that the main thread is correctly identified as "main" (with an undefined worker index) even when running in zero-worker mode (setMainIsWorker is true). It introduces a helper function parseStatusKey to parse component names, thread labels, and public names, and updates the aggregation and request handler logic accordingly. Comprehensive unit tests are added to verify these behaviors. I have no feedback to provide as there are no review comments.

kriszyp and others added 2 commits October 27, 2026 16:30
Use a shared parseStatusKey helper in components/status/crossThread.ts so StatusAggregator.aggregate splits on the last '@' rather than the first, keeping '@scope/pkg' component names intact instead of collapsing them under an empty-string key.

Check isMainThread from node:worker_threads instead of getWorkerIndex() === undefined in CrossThreadStatusCollector and componentStatusRequestHandler so main-thread statuses stay labelled 'main' when threads.count is 0 (setMainIsWorker).

Dispatch-Task: harper-status-thread-label-and-main
Co-Authored-By: Gemini <noreply@google.com>
Share getLocalStatusOnly between collect() and the ITC-failure fallback, cover the worker-thread branch in unit tests, and restore prior setMainIsWorker state on teardown.

Dispatch-Task: harper-status-thread-label-and-main
Co-Authored-By: Gemini <noreply@google.com>
@kriszyp
kriszyp force-pushed the fix/status-thread-label-and-main branch from b8c71de to 0661aa7 Compare October 27, 2026 22:36
@kriszyp
kriszyp marked this pull request as ready for review October 29, 2026 17:25
@kriszyp
kriszyp merged commit 0c56f54 into main Oct 29, 2026
101 of 104 checks passed
@kriszyp
kriszyp deleted the fix/status-thread-label-and-main branch October 29, 2026 17:25
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