gabriel / musehub public
proposal-issue-linking-bug.md markdown
100 lines 4.5 KB
Raw
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago

Bug: stale merged proposals incorrectly linked to unrelated issues

Observed

Issue #111 ("MWP-8: bust fetch-mpack cache on repair and force-push") shows a linked proposal it has no relationship to:

  • Proposal: sha256:e83b2606f750a38f5064d2adb51473e2d6afa4b936e328aa9924f61e01b2d873
  • Proposal title: "Asyncpg Caps Query Parameters"
  • Proposal state: merged
  • Proposal branch: feat/adding-debug-logs-to-staging
  • Proposal created: 2026-06-11 (≈ 20 days before this was noticed)
  • Issue #111 created: 2026-06-26

The proposal is about asyncpg query-parameter capping during a debug-logging session. Issue #111 is about cache invalidation in musehub_fetch_mpack_cache after repair endpoints and force-push. There is no shared vocabulary in their titles, bodies, or branch names.

Why this is a bug

A merged proposal that predates an issue by two weeks should never be auto-linked to that issue. Specifically:

  1. Already merged. Merged proposals are closed artifacts — they should not be retroactively associated with issues filed after they merged.
  2. No explicit reference. The issue body contains no mention of the proposal ID, the branch name feat/adding-debug-logs-to-staging, or any asyncpg-related keyword. The proposal body does not reference #111.
  3. Wrong direction. If the linking heuristic is symbol-overlap (both touched musehub service/DB files), that signal is too weak to establish a link — nearly every musehub change touches the same small set of service files.

Hypothesised cause

The most likely explanation is a symbol-anchor or file-overlap heuristic that fires when:

  • An issue is created or updated with symbolAnchors pointing to files that were also changed in some proposal's diff, and
  • The heuristic does not filter out already-merged proposals.

Issue #111's symbolAnchors include:

musehub/services/musehub_gc.py::gc_fetch_mpack_cache
musehub/services/musehub_wire_push.py::wire_repair_commit
musehub/services/musehub_wire_push.py::wire_push_unpack_mpack
musehub/services/musehub_wire_fetch.py::wire_fetch_mpack
musehub/db/musehub_repo_models.py::MusehubFetchMPackCache

The asyncpg proposal (feat/adding-debug-logs-to-staging) likely touched one or more of these files (asyncpg connection setup touches the DB layer). If the overlap threshold is "any file in common," false positives are guaranteed on a small codebase where every change goes through the same service layer.

A secondary hypothesis: the link was written at issue-update time (when the issue body was last pushed), not at issue-creation time, and the heuristic rescans all open+merged proposals rather than only open ones.

Expected behaviour

A proposal should be linked to an issue only when at least one of the following holds:

  • The proposal body or commit message contains an explicit #<issue-number> or issue/<issue-id> reference.
  • A user or agent explicitly calls a "link proposal → issue" API.
  • The proposal was opened after the issue was filed and shares a branch that descends from the issue's anchor commit.

Merged proposals should be excluded from auto-linking entirely unless there is an explicit reference — their diff is historical and the relationship would need to be intentional.

Reproduction steps

  1. Open https://staging.musehub.ai/gabriel/musehub/issues/111 in a browser.
  2. Observe the linked proposal sha256:e83b2606... ("Asyncpg Caps Query Parameters").
  3. Open the proposal — note it is merged, predates the issue, and shares no explicit reference with #111.

Impact

  • Incorrect UI signal: developers following the proposal link expect to find related work and instead find an unrelated merged PR.
  • Trust erosion: auto-linking that fires on weak signals makes the feature indistinguishable from noise.
  • Potential data integrity: if linked proposals gate any workflow (e.g., issue close requires linked proposal to be merged), false links could block or prematurely unblock issue state transitions.

Suggested fix surface

musehub/api/routes/ or musehub/services/ — wherever proposal→issue association is written. Look for:

  • The write path that creates a proposal_issue_link (or equivalent) row.
  • Whether it filters state == "open" proposals before matching.
  • The overlap threshold used for symbol/file heuristics.

A conservative fix: only link a proposal to an issue when the proposal body or any of its commit messages contain an explicit #<n> reference that resolves to the issue number in the same repo.

File History 3 commits
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 8 days ago
sha256:408916fc5973ba59c6e4eebaa80ebdcc801c0a63205651e25009d11548f79454 chore: bump version to 0.2.0.dev2 — nightly.2, matching muse Sonnet 4.6 patch 11 days ago