Skip to content

fix(convoy): cross-database dependency resolution fails for multi-rig towns #2624

@Cdfghglz

Description

@Cdfghglz

Problem

In multi-rig Gas Town setups where each rig has its own Dolt database, convoy auto-dispatch is completely broken. Convoys are always hq-cv-* (stored in the HQ database), but tracked issues use rig-specific prefixes (e.g., ds-* in the dashboard database). The dependency resolution cannot cross this database boundary.

Symptoms

  • gt convoy status hq-cv-xxx → "Progress: 0/0 completed" despite tracking 14 issues
  • gt convoy launch hq-cv-xxx → "tracks no beads"
  • bd dep list hq-cv-xxx -v → finds 14 raw "external-deps" but reports "has no dependencies"
  • Daemon logs: "Convoy hq-cv-xxx: empty but within grace period"
  • gt convoy stage <epic> works (resolves deps at stage time) but the created convoy can't be launched or tracked

Root Cause

Two code paths in internal/convoy/operations.go fail for cross-database deps:

  1. getConvoyTrackedIssues() (line ~293): Calls store.GetDependenciesWithMetadata() on the HQ store, which returns external:ds:ds-xxx refs. The fallback fetchCrossRigBeadStatus() (line ~336) resolves these via subprocess bd show, but the convoy status/launch commands don't use this path — they see 0 tracked beads.

  2. isIssueBlocked() (line ~193): Calls store.GetDependenciesWithMetadata() directly with NO cross-database fallback. Returns stale/empty metadata for cross-rig blocking deps, causing incorrect dispatch decisions.

The Catch-22

  • hq-* prefixed issues → same DB as convoy ✓ → but rigForIssue() returns empty (can't route) ✗
  • ds-* prefixed issues → rigForIssue() routes correctly ✓ → but convoy can't resolve deps ✗

Impact

Multi-rig towns cannot use convoy auto-dispatch at all. Manual gt sling per wave is required, defeating the purpose of the convoy system.

Related Issues

Consolidates: #2605, #2606, #2604, #2423. Prior closed instances: #2373, #992, #915.

Proposed Fix

The daemon already has map[string]beadsdk.Storage with all rig stores open (daemon.go:openBeadsStores()). The data is available — just not wired through to the convoy operations.

Create a multi-store resolver that:

  1. Accepts the store map from the daemon
  2. Resolves issue IDs by extracting prefix → looking up the correct store
  3. Provides ResolveIssues(ids, stores) used by both getConvoyTrackedIssues() and isIssueBlocked()

This replaces the fragile subprocess fetchCrossRigBeadStatus() with direct store queries — faster, no external bd dependency, and consistently applied to ALL resolution paths.

Scope: ~200-250 lines across 3 files. Zero risk to single-DB setups (multi-store lookup only activates when local store returns empty).

Environment

  • Gas Town version: main (4d35143)
  • Beads: 0.59.0
  • Setup: Multi-rig town with per-rig Dolt databases (dashboard=ds, nav_server=ns, etc.)
  • Daemon running with convoy auto-feed enabled

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions