Repository navigation
[Bug]: required dashboard-browser (3) shard asserts before the scoped Goal snapshot fan-out settles #6886
Description
Importance
This is a merge-gate outage, not a cosmetic test cleanup: the required dashboard-browser (3) job and the aggregate checks job are red on main, so every PR whose core tests run loses a required check. The same shard is red on open PRs #6877, #6876, #6874, and #6496, and maintainers must currently admin-bypass the gate instead of trusting it. The failure is in the existing goal-hierarchy regression added/extended by #6834; it does not require a product rewrite.
Problem
The browser scenario records every per-Goal status request and asserts immediately after a root-scoped reload. The reload's directory read completes first, then the two-worker snapshot fan-out starts. Under the coverage instrumentation used by the required lane, page.reload({waitUntil: "networkidle"}) and the selected-row wait can both settle after only the first worker's requests have been issued. The test therefore observes calibration and research, but not portfolio or graph, even though those requests are issued shortly afterwards by the same scoped load.
The same race exists earlier in the scenario: statusReads is cleared before the initial unscoped load has necessarily drained, so slower coverage runs can attribute legitimate initial full-workspace reads to the scoped action.
Minimal reproduction
- Check out
a72dcb21a2906fccf099b11959725b595aa826ed. - Prepare the dashboard test dependencies:
cd apps/presentation/dashboard && npm ci --ignore-scripts. - Run the scenario with the same coverage setting as the required lane:
$env:LOOPX_PERSONAL_WORKSPACE_SCENARIO = "goal-hierarchy"
$env:LOOPX_DASHBOARD_COVERAGE = "1"
$env:LOOPX_PLAYWRIGHT_PACKAGE = "$PWD/node_modules/playwright"
node ../../../examples/personal-workspace-browser-smoke.mjsThe failure reproduces consistently in this environment. Running the same scenario without LOOPX_DASHBOARD_COVERAGE=1 passes, which distinguishes the assertion timing from a missing product request.
Expected behavior
The regression should wait until all four subtree snapshot requests have been observed before asserting that no unrelated Goal state was opened. It should likewise wait for the initial full-workspace read to drain before resetting its request log. The product should still issue only research, portfolio, calibration, and graph for the scoped reload.
Actual behavior
Hosted required-lane failure:
AssertionError [ERR_ASSERTION]: opening a scoped workspace reads its recursive subtree without opening unrelated Goal state
actual: [ 'calibration', 'research' ]
expected: [ 'calibration', 'graph', 'portfolio', 'research' ]
at examples/personal-workspace-browser/goal-hierarchy.mjs:119
Local instrumentation with coverage shows the missing portfolio and graph requests are issued immediately after the row assertion resolves; they are not omitted by scopeWorkspaceDirectory() or loadWorkspaceGoalSnapshots().
Evidence
- Failing
mainrun: https://github.com/loopx-project/loopx/actions/runs/39244959697 - Failing required job: https://github.com/loopx-project/loopx/actions/runs/39244959697/job/118042807735
- Same shard red on open PRs: fix(quota): honor agent choice over advisory Todo priority #6877, feat(content-ops): add media providers and Goal artifact production #6876, refactor(todos): compose full readback in one TypeScript transaction #6874, fix(chat): keep completed-history pages independent across Goals #6496
- Follow-up to fix(workspace): read only the selected Goal subtree #6834, which added the scoped-read assertion, and
d8c62a0bfa2004210a5deda3cf8a3ceb4747fbb2, which extended the scenario.
Additional context
The local host uses a newer Node runtime than CI, but the assertion is timing-sensitive rather than runtime-version-sensitive: the same early-settle behavior is visible in the hosted job. A deterministic request barrier should make the regression prove the product scope without depending on CPU speed or Playwright's network-idle heuristic.
Activity