Skip to content

fix(queue): require a selected project before loading work#3765

Merged
BunsDev merged 38 commits into
mainfrom
agent/queue-project-readiness
Jul 24, 2026
Merged

fix(queue): require a selected project before loading work#3765
BunsDev merged 38 commits into
mainfrom
agent/queue-project-readiness

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 24, 2026

Copy link
Copy Markdown
Member

Re-lands #3743 by @CompleteDotTech with the open review thread addressed. The original fork branch was deleted after the fork moved, so the PR head is orphaned and cannot receive the fix; this branch carries all 21 original commits with their authorship intact.

Summary

  • persist a Queue-specific selected project and validate it before every Queue load
  • require Queue project selection in onboarding and reopen it at launch when the path is stale or unavailable
  • add a Queue Generate action that initializes Beads only in the selected Git repository

Review-feedback fix (on top of #3743)

  • beadsWorkspaceStatus() previously accepted a canonical-path mismatch for a contained .beads directory (&&), weaker than resolveSafeBeadsWorkspace() (||) — readiness could report ready where /api/beads answers 422 unsafe. It now delegates the existing-directory verdict to resolveSafeBeadsWorkspace() so both surfaces share one safety contract by construction, with a swapped in-repo .beads symlink regression test.
  • canonicalized mkdtemp roots in the readiness and workspace tests (macOS /var/private/var symlink broke them locally; CI Linux was unaffected).

Validation

  • pnpm typecheck
  • focused: queue-project-readiness.test.ts, beads-workspace.test.ts, api/queue/readiness/route.test.ts
  • pnpm check:tests-wired

Merge note

Squash-merge with an explicit message preserving:
Co-authored-by: Timothy Wayne Gregg <5861166+CompleteDotTech@users.noreply.github.com>

Closes cave-dsbj

CompleteDotTech and others added 30 commits July 24, 2026 02:38
The new dismissal override (a stored dismissal must not mask a missing
Queue project) force-opened the Onboarding dialog over every surface in
CI: the daemon-less e2e run (COVEN_CAVE_E2E=1) never has a selected
project, so all 15 pre-existing specs — which follow the documented
contract of setting cave:onboarding:dismissed=1 and mocking /api/* —
timed out behind the aria-modal overlay ('subtree intercepts pointer
events', 25m job timeout).

Stub the project step ok in the harness, mirroring the existing
COVEN_CAVE_E2E short-circuits (playwright.config.ts, mobile-access-
provision.ts). Real runs keep the readiness probe; onboarding-wizard
and familiar-work-queue specs mock this route wholesale, so project-
readiness coverage is unchanged.

Verified locally: route + gate unit tests ok; calendar-month-grid (a
previously pointer-blocked legacy spec), all 13 onboarding-wizard and
all 14 familiar-work-queue tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With the dismissed short-circuit gone every boot fetches
/api/onboarding/status for real; its cold compile + probes race the
lazy code-rail chunk on pixel-5 and the sheet renders empty past the
5s expect (the exact E2E failure on this PR's last run). Mock the
route like familiar-work-queue.spec.ts already does — specs are
self-contained per the harness contract.

Verified: code-rail-sheet green across pixel-5/iphone-13/desktop with
--repeat-each=2 (was: deterministic pixel-5 fail at this tip).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CompleteDotTech and others added 8 commits July 24, 2026 02:38
Queue readiness previously accepted a canonical-path mismatch for a
contained .beads directory (&&), while resolveSafeBeadsWorkspace treats
any mismatch as unsafe (||) — so readiness could report ready where
/api/beads answers 422 unsafe. Delegate the existing-directory verdict
to resolveSafeBeadsWorkspace so both surfaces share one contract, and
cover the swapped in-repo .beads symlink in the readiness test.

Also canonicalize mkdtemp roots in the readiness and workspace tests so
they pass on macOS, where os.tmpdir() sits behind the /var symlink.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
His fork branch for #3743 became unreachable, so the work re-lands
through this internal branch; record the attribution it is due.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Pull request overview

This PR makes the Queue surface explicitly depend on a persisted, validated “Queue project” selection (a concrete Git repo root) before reading or mutating Beads work, and ensures onboarding/startup reopens when that selection is missing or stale.

Changes:

  • Add a Queue project readiness contract (persisted selection, validation, Generate bd init, and explicit projectRoot scoping for Queue reads/mutations).
  • Update onboarding and startup gating to require Git + Queue project selection (with E2E seeding/mocks to keep daemon-less specs stable).
  • Align subprocess PATH handling for Queue tooling (git/gh/bd) and harden Beads workspace safety via a shared resolver.

Reviewed changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/onboarding-wizard.spec.ts Updates onboarding E2E expectations for the new required Git + Queue project steps.
tests/mobile/code-rail-sheet.spec.ts Mocks onboarding status route now that status is probed even when onboarding is dismissed.
tests/familiar-work-queue.spec.ts Extends Queue E2E coverage for projectRoot scoping, project switching, and Generate conflict behavior.
tests/chat-boot-landing.spec.ts Adds baseline spec asserting dismissed onboarding remains closed when Queue selection is seeded.
src/lib/surface-warmup-registry.ts Removes the unscoped tasks:queue warmup resource now that Queue requires an explicit projectRoot.
src/lib/server/issue-worktree-provision.ts Uses caveToolSpawnEnv() for git subprocesses in repo provisioning.
src/lib/server/beads-workspace.ts Introduces shared, symlink-safe .beads workspace resolver.
src/lib/server/beads-workspace.test.ts Adds regression test for swapped .beads symlink safety.
src/lib/server/beads-cli.ts Switches bd subprocess env to caveToolSpawnEnv() while keeping secrets scrubbed.
src/lib/server/backup-manifest.ts Adds Queue selection file to backup manifest.
src/lib/server/backup-manifest.test.ts Verifies Queue selection is included in backup listing.
src/lib/queue-project-selection.ts Adds publish/subscribe helpers to broadcast Queue project selection across windows.
src/lib/queue-project-readiness.ts Implements persisted selection storage, Git validation, Beads workspace checks, and readiness caching.
src/lib/queue-project-readiness.test.ts Exercises readiness codes, cache behavior, and safety invariants (including swapped .beads symlink).
src/lib/onboarding-gate.ts Treats Queue project step as structural for auto-open onboarding logic.
src/lib/onboarding-gate.test.ts Adds test that missing Queue project reopens onboarding even when daemon is down.
src/lib/coven-bin.ts Adds caveToolSpawnEnv() and refactors PATH augmentation ordering/caching.
src/lib/coven-bin.test.ts Asserts Queue tools prefer the launch PATH and validates Queue spawn sites use caveToolSpawnEnv().
src/components/workspace.tsx Always probes onboarding status at startup, but reopens onboarding when Queue project needs repair.
src/components/onboarding-overlay.tsx Adds required Git + Queue project steps and UI for selecting a Queue project via ProjectPicker.
src/components/onboarding-model.ts Adds required project step to onboarding model type.
src/components/onboarding-guided-steps.test.ts Pins out-of-order selection protection logic in onboarding UI.
src/components/familiar-work-queue-view.tsx Requires readiness first, scopes Queue fetches/mutations by projectRoot, and adds Generate recovery.
src/components/familiar-work-queue-view.test.ts Updates string-contract assertions for projectRoot scoping and readiness-driven behavior.
src/components/familiar-work-queue-sections.tsx Threads projectRoot into bead detail reads.
src/components/board-view.tsx Stops invalidating the removed tasks:queue warm resource.
src/components/asana-queue-strip.tsx Threads Queue-selected projectRoot into Asana → bead filing and resets “filed” per project.
src/app/api/queue/readiness/route.ts Adds loopback-only Queue readiness route with select + per-repo Generate lock contract.
src/app/api/queue/readiness/route.test.ts Tests Generate identity binding, locking/idempotency, and partial-init handling.
src/app/api/onboarding/status/route.ts Adds Queue project step and makes Git required (not optional) to support Queue selection.
src/app/api/onboarding/status/route.test.ts Updates assertions to match required Git + cached Queue readiness integration.
src/app/api/beads/route.ts Requires explicit projectRoot, uses shared workspace resolver, and reuses readiness probe output for mode=ready.
src/app/api/beads/route.test.ts Validates projectRoot scoping across reads/mutations and subprocess cwd/BEADS_DIR correctness.
src/app/api/beads/prs/route.ts Requires explicit projectRoot and switches gh env to caveToolSpawnEnv().
src/app/api/api-contracts.test.ts Registers /queue/readiness in API contract inventory with local origin guard.
src-tauri/src/sidecar_archive_manifest.rs Bumps MAX_FILE_COUNT budget for sidecar archive manifest.
scripts/sidecar-runtime-smoke.mjs Updates sidecar runtime smoke budget to the new file-count ceiling.
scripts/sidecar-runtime-closure.test.mjs Updates sidecar runtime closure test budget for fileCount.
scripts/sidecar-runtime-closure.mjs Updates documented and enforced runtime file-count budget.
scripts/sidecar-bundle-deps.test.mjs Updates assertions for the revised runtime file-count budget.
scripts/run-tests.mjs Wires new tests into suites and alias loader.
playwright.config.ts Seeds Queue selection file for daemon-less E2E runs.
CONTRIBUTORS.md Adds contributor credit entry for the original Queue project readiness work.
Comments suppressed due to low confidence (1)

src/lib/queue-project-selection.ts:66

  • BroadcastChannel will often echo the message back to the sending window. Without a duplicate guard, onMessage can re-dispatch the same selection that publishQueueProjectSelection() already dispatched locally, causing duplicate Queue reloads.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +42 to +44
function dispatch(project: QueueProjectSelection | null): void {
window.dispatchEvent(new CustomEvent(QUEUE_PROJECT_SELECTED_EVENT, { detail: { project } }));
}
@BunsDev
BunsDev merged commit 79d9faf into main Jul 24, 2026
16 checks passed
@BunsDev
BunsDev deleted the agent/queue-project-readiness branch July 24, 2026 09:34
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.

3 participants