Skip to content

Debug PR #849 describer cross-project ticket leak - #852

Merged
adriandemian merged 7 commits into
mainfrom
ralphx/ralphx/agent-b4e30334
Jul 22, 2026
Merged

Debug PR #849 describer cross-project ticket leak#852
adriandemian merged 7 commits into
mainfrom
ralphx/ralphx/agent-b4e30334

Conversation

@adriandemian

@adriandemian adriandemian commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes cross-project ticket link contamination in ClickUp reconciliation for agent workspaces. When a PR title was auto-normalized with a ticket prefix or after a base-update merge with a stale local base ref, RalphX would link conversations to tickets in unrelated projects.

Root causes:

  1. PR title and body were accepted as link evidence, allowing RalphX's own normalizer output to self-validate the link it created (title-only contamination loop)
  2. git log base..HEAD after a stale-base merge includes commits imported from the base itself, not just branch-authored commits (base-commit leak)

Fixes:

  • New GitService::get_branch_authored_commits() — Uses git log --first-parent --not base origin/base to walk only the branch's own commit line, excluding commits imported by base-update merges. Tolerates missing origin/<base> via --ignore-missing.

  • Evidence scoping in reconcile_clickup_pr_to_conversation() — PR title and body are now discovery-only; only workspace-owned signals (branch name, branch-authored commit subjects) can authorize a ticket link. Filters evidence before matching candidates.

  • Reconciliation uses scoped commits — Replaced get_commits_between() with get_branch_authored_commits() for ticket candidate discovery.

  • Regression tests — Three new tests verify title-only, body-only, and commit-subject evidence paths; two git-service tests verify the first-parent walk excludes imported commits and handles missing remote refs.

User Impact

Users will no longer see spurious cross-project ClickUp links created when running agent workspaces on stale base refs or when PR titles are auto-normalized with ticket prefixes.

Technical Context

ClickUp ticket linking in external PR reconciliation must trust only durable workspace-owned signals (branch name chosen by the branch creator, commit subjects written by the branch author). PR title/body are ephemeral, often generated or edited by automation, and can carry unrelated context.

The stale-base-ref bug occurs because after git merge origin/<base> into a branch whose local <base> ref is outdated, commits reachable from HEAD but not from the stale local ref appear as "new" in a base..HEAD walk — these are actually the advanced base's commits, not branch work. First-parent walk + explicit exclusion of both local and remote base refs keeps evidence scoped correctly.

Risks / Follow-Ups

None. Only changes what counts as valid link evidence; existing valid evidence (branch name, commit subjects) continues to work. All association and git-service tests pass, including three new regressions for each contamination vector.


Generated by RalphX

@adriandemian adriandemian changed the title fix: prevent cross-project ticket contamination in PR reconciliation fix: prevent cross-project ticket contamination in PR title prefixing Jul 22, 2026
@adriandemian adriandemian changed the title fix: prevent cross-project ticket contamination in PR title prefixing Debug PR #849 describer cross-project ticket leak Jul 22, 2026
@adriandemian
adriandemian marked this pull request as ready for review July 22, 2026 17:08
@adriandemian
adriandemian enabled auto-merge (squash) July 22, 2026 17:08
@adriandemian
adriandemian disabled auto-merge July 22, 2026 17:19
@adriandemian
adriandemian enabled auto-merge (squash) July 22, 2026 17:21
@adriandemian
adriandemian disabled auto-merge July 22, 2026 17:33
…ciliation test

PR title/body are now discovery-only evidence for ClickUp linking, so the
reconciliation test must carry the ticket token in a workspace-owned signal
(the branch name) for the link to be authorized.
@adriandemian
adriandemian enabled auto-merge (squash) July 22, 2026 17:54
@adriandemian
adriandemian disabled auto-merge July 22, 2026 18:35
@adriandemian
adriandemian merged commit 3f0626c into main Jul 22, 2026
36 checks passed
@adriandemian
adriandemian deleted the ralphx/ralphx/agent-b4e30334 branch July 22, 2026 18:35
@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.23529% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src-tauri/src/application/git_service/query.rs 86.48% 5 Missing ⚠️
...tion/agent_workspace_external_pr_reconciliation.rs 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

adriandemian added a commit that referenced this pull request Jul 23, 2026
* Shared Agent Runtime Picker and Overrides (#832)

* feat: add scoped agent runtime overrides

* feat: add scoped agent runtime overrides

* fix: bump workspace review migration schema version

* fix: refresh stale workspace review fixer receipts

* fix: resolve workspace review CI blockers

* Block Workspace Review During Unfinished Git Operations (#826)

* feat: Block Workspace Review During Unfinished Git Operations

* test: seed valid base commit in PR recovery

* test: satisfy workspace review patch coverage

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* fix: refresh stale workspace review fixer receipts

* fix: complete workspace repair rebase

* fix: dedupe workspace review repair helpers

* fix: repair runtime override CI fixtures

* fix: align runtime picker CI expectations

* feat: Reuse provider picker for agent role settings

* feat: Shared Agent Runtime Picker and Overrides

* fix: isolate reviewer provider test from fast catalog

* fix: isolate provider default test from fast catalog

* feat: Shared Agent Runtime Picker and Overrides

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Debug PR #849 describer cross-project ticket leak (#852)

* feat: Debug PR #849 describer cross-project ticket leak

* feat: Debug PR #849 describer cross-project ticket leak

* fix: resolve clippy manual_contains in git_service query tests

* test: authorize clickup link via branch evidence in external PR reconciliation test

PR title/body are now discovery-only evidence for ClickUp linking, so the
reconciliation test must carry the ticket token in a workspace-owned signal
(the branch name) for the link to be authorized.

* Scope publish progress to live attempts and retire orphaned toasts (#853)

* fix: settle orphaned publish operation toasts

* test: align publish pane coverage

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Fix usage stats calculation drift (#841)

* feat: correct agent usage accounting

* fix: update pending usage stats assertion

* feat: Fix usage stats calculation drift

* feat: Fix usage stats calculation drift

* fix: mock usage events in provider tests

* fix: stabilize persisted artifact pane test

* fix: update delegated Codex usage fixture

* fix: mark uncounted usage totals unavailable

* fix: harden usage accounting review findings

* fix: correct delegated token expectation

* fix: align delegated timeline fixture

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Remove legacy Claude-only team mode code (#810)

* feat: remove legacy Claude team mode

* fix: restore filesystem enforcement derivation

* fix: preserve native team runtime after merge

* refactor: remove legacy Claude team mode

* feat: Remove legacy Claude-only team mode code

* feat: Remove legacy Claude-only team mode code

* feat: Remove legacy Claude-only team mode code

* feat: Remove legacy Claude-only team mode code

* fix: reconcile merged Rust call sites

* fix: repair legacy team removal test fallout

* fix: order tasks feature state migration

* fix: remove stale folder context export

* fix: stabilize persisted artifact pane test

* fix: align workspace review test state

* feat: Remove legacy Claude-only team mode code

* fix: align agent panel send tests

* fix: align plan proposal message tests

* fix: align streaming test call signature

* feat: Remove legacy Claude-only team mode code

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Fix workspace review deadlock on conflicts (#854)

* fix: break workspace review repair deadlock

* fix: validate PR fix against workspace HEAD

* test: align stale review handoff recovery assertion

* test: align workspace review recovery assertions

* test: align repair completion error assertion

* test: seed active workspace review monitor

* test: align stale repair PR status assertion

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Fix harness-aware agent chat delivery (#856)

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Agent Launch Reservation and PR Autofix Recovery Hardening (#851)

* fix: harden agent launch reservation recovery

* fix: align integration registry test doubles

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* fix: harden agent launch reservation recovery

* fix: align integration registry test doubles

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* Shared Agent Runtime Picker and Overrides (#832)

* feat: add scoped agent runtime overrides

* feat: add scoped agent runtime overrides

* fix: bump workspace review migration schema version

* fix: refresh stale workspace review fixer receipts

* fix: resolve workspace review CI blockers

* Block Workspace Review During Unfinished Git Operations (#826)

* feat: Block Workspace Review During Unfinished Git Operations

* test: seed valid base commit in PR recovery

* test: satisfy workspace review patch coverage

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* fix: refresh stale workspace review fixer receipts

* fix: complete workspace repair rebase

* fix: dedupe workspace review repair helpers

* fix: repair runtime override CI fixtures

* fix: align runtime picker CI expectations

* feat: Reuse provider picker for agent role settings

* feat: Shared Agent Runtime Picker and Overrides

* fix: isolate reviewer provider test from fast catalog

* fix: isolate provider default test from fast catalog

* feat: Shared Agent Runtime Picker and Overrides

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* fix: remove duplicate workspace review action

* fix: restore PR autofix compilation

* fix: expose PR autofix classification to recovery

* fix: expose PR autofix issue to recovery

* fix: retain stale repair recovery summary

* fix: complete stale running agent registry mock

* fix: align PR autofix integration fixtures

* fix: align queued message test call

* fix: make PR supervision recovery claims atomic

* fix: align PR supervision regression fixtures

* fix: align PR autofix route test with immediate dispatch

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* fix: align plan PR autofix route fixture

* test: cover launch recovery ownership branches

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* chore: prepare v0.76.0 daily release

* Fix user message text wrapping in agent chat (#858)

* feat: Fix user message text wrapping in agent chat

* test(visual): update compact split composer baseline for user bubble wrapping fix

* feat: Review PR #854 for accuracy (#859)

* feat: Show publishing state on commit & publish (#862)

* fix: scope legacy team migration FK check to introduced violations (#863)

* fix: scope legacy team migration FK check to introduced violations

The v20260720140000 legacy Claude team removal validated integrity with a
database-wide `pragma_foreign_key_check`. Production never enables
`PRAGMA foreign_keys`, so live databases carry orphan rows this migration
neither created nor cleans up. Those pre-existing violations were counted
as migration damage, so the migration failed, AppState initialization
panicked, and the app aborted on every launch with no way to recover.

Baseline the violations inside the transaction and gate only on ones the
migration introduces. Violations are keyed by constraint rather than rowid
so the comparison survives the table rewrites the migration performs, and
the error now names the offending child/parent tables.

* docs: correct foreign-key enforcement rationale in legacy team migration

Foreign keys are enforced in production: libsqlite3-sys builds bundled
SQLite with -DSQLITE_DEFAULT_FOREIGN_KEYS=1. Orphan rows accumulate
because migrations that rewrite tables disable enforcement, not because
it is never enabled. Comments only; behavior unchanged.

* Fix delegate rehydration and duplicate widgets (#857)

* fix: rehydrate delegates without duplicates

* test: cover streaming task rehydration

* fix: preserve delegate card during snapshot suppression

* test: stabilize terminal publish visual scenario

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Compact agent workspace toolbar status

* fix: settle workspace reviews after accepted completion (#869)

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

---------

Co-authored-by: Laza Bogdan <lazabogdan@users.noreply.github.com>
Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
adriandemian added a commit that referenced this pull request Jul 24, 2026
* Implement Commit & Publish header alignment run 1 (#868)

* Shared Agent Runtime Picker and Overrides (#832)

* feat: add scoped agent runtime overrides

* feat: add scoped agent runtime overrides

* fix: bump workspace review migration schema version

* fix: refresh stale workspace review fixer receipts

* fix: resolve workspace review CI blockers

* Block Workspace Review During Unfinished Git Operations (#826)

* feat: Block Workspace Review During Unfinished Git Operations

* test: seed valid base commit in PR recovery

* test: satisfy workspace review patch coverage

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* fix: refresh stale workspace review fixer receipts

* fix: complete workspace repair rebase

* fix: dedupe workspace review repair helpers

* fix: repair runtime override CI fixtures

* fix: align runtime picker CI expectations

* feat: Reuse provider picker for agent role settings

* feat: Shared Agent Runtime Picker and Overrides

* fix: isolate reviewer provider test from fast catalog

* fix: isolate provider default test from fast catalog

* feat: Shared Agent Runtime Picker and Overrides

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Debug PR #849 describer cross-project ticket leak (#852)

* feat: Debug PR #849 describer cross-project ticket leak

* feat: Debug PR #849 describer cross-project ticket leak

* fix: resolve clippy manual_contains in git_service query tests

* test: authorize clickup link via branch evidence in external PR reconciliation test

PR title/body are now discovery-only evidence for ClickUp linking, so the
reconciliation test must carry the ticket token in a workspace-owned signal
(the branch name) for the link to be authorized.

* Scope publish progress to live attempts and retire orphaned toasts (#853)

* fix: settle orphaned publish operation toasts

* test: align publish pane coverage

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Fix usage stats calculation drift (#841)

* feat: correct agent usage accounting

* fix: update pending usage stats assertion

* feat: Fix usage stats calculation drift

* feat: Fix usage stats calculation drift

* fix: mock usage events in provider tests

* fix: stabilize persisted artifact pane test

* fix: update delegated Codex usage fixture

* fix: mark uncounted usage totals unavailable

* fix: harden usage accounting review findings

* fix: correct delegated token expectation

* fix: align delegated timeline fixture

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Remove legacy Claude-only team mode code (#810)

* feat: remove legacy Claude team mode

* fix: restore filesystem enforcement derivation

* fix: preserve native team runtime after merge

* refactor: remove legacy Claude team mode

* feat: Remove legacy Claude-only team mode code

* feat: Remove legacy Claude-only team mode code

* feat: Remove legacy Claude-only team mode code

* feat: Remove legacy Claude-only team mode code

* fix: reconcile merged Rust call sites

* fix: repair legacy team removal test fallout

* fix: order tasks feature state migration

* fix: remove stale folder context export

* fix: stabilize persisted artifact pane test

* fix: align workspace review test state

* feat: Remove legacy Claude-only team mode code

* fix: align agent panel send tests

* fix: align plan proposal message tests

* fix: align streaming test call signature

* feat: Remove legacy Claude-only team mode code

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Fix workspace review deadlock on conflicts (#854)

* fix: break workspace review repair deadlock

* fix: validate PR fix against workspace HEAD

* test: align stale review handoff recovery assertion

* test: align workspace review recovery assertions

* test: align repair completion error assertion

* test: seed active workspace review monitor

* test: align stale repair PR status assertion

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Fix harness-aware agent chat delivery (#856)

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Agent Launch Reservation and PR Autofix Recovery Hardening (#851)

* fix: harden agent launch reservation recovery

* fix: align integration registry test doubles

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* fix: harden agent launch reservation recovery

* fix: align integration registry test doubles

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* Shared Agent Runtime Picker and Overrides (#832)

* feat: add scoped agent runtime overrides

* feat: add scoped agent runtime overrides

* fix: bump workspace review migration schema version

* fix: refresh stale workspace review fixer receipts

* fix: resolve workspace review CI blockers

* Block Workspace Review During Unfinished Git Operations (#826)

* feat: Block Workspace Review During Unfinished Git Operations

* test: seed valid base commit in PR recovery

* test: satisfy workspace review patch coverage

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* fix: refresh stale workspace review fixer receipts

* fix: complete workspace repair rebase

* fix: dedupe workspace review repair helpers

* fix: repair runtime override CI fixtures

* fix: align runtime picker CI expectations

* feat: Reuse provider picker for agent role settings

* feat: Shared Agent Runtime Picker and Overrides

* fix: isolate reviewer provider test from fast catalog

* fix: isolate provider default test from fast catalog

* feat: Shared Agent Runtime Picker and Overrides

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* fix: remove duplicate workspace review action

* fix: restore PR autofix compilation

* fix: expose PR autofix classification to recovery

* fix: expose PR autofix issue to recovery

* fix: retain stale repair recovery summary

* fix: complete stale running agent registry mock

* fix: align PR autofix integration fixtures

* fix: align queued message test call

* fix: make PR supervision recovery claims atomic

* fix: align PR supervision regression fixtures

* fix: align PR autofix route test with immediate dispatch

* feat: Agent Launch Reservation and PR Autofix Recovery Hardening

* fix: align plan PR autofix route fixture

* test: cover launch recovery ownership branches

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* chore: prepare v0.76.0 daily release

* Fix user message text wrapping in agent chat (#858)

* feat: Fix user message text wrapping in agent chat

* test(visual): update compact split composer baseline for user bubble wrapping fix

* feat: Review PR #854 for accuracy (#859)

* feat: Show publishing state on commit & publish (#862)

* fix: scope legacy team migration FK check to introduced violations (#863)

* fix: scope legacy team migration FK check to introduced violations

The v20260720140000 legacy Claude team removal validated integrity with a
database-wide `pragma_foreign_key_check`. Production never enables
`PRAGMA foreign_keys`, so live databases carry orphan rows this migration
neither created nor cleans up. Those pre-existing violations were counted
as migration damage, so the migration failed, AppState initialization
panicked, and the app aborted on every launch with no way to recover.

Baseline the violations inside the transaction and gate only on ones the
migration introduces. Violations are keyed by constraint rather than rowid
so the comparison survives the table rewrites the migration performs, and
the error now names the offending child/parent tables.

* docs: correct foreign-key enforcement rationale in legacy team migration

Foreign keys are enforced in production: libsqlite3-sys builds bundled
SQLite with -DSQLITE_DEFAULT_FOREIGN_KEYS=1. Orphan rows accumulate
because migrations that rewrite tables disable enforcement, not because
it is never enabled. Comments only; behavior unchanged.

* Fix delegate rehydration and duplicate widgets (#857)

* fix: rehydrate delegates without duplicates

* test: cover streaming task rehydration

* fix: preserve delegate card during snapshot suppression

* test: stabilize terminal publish visual scenario

---------

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

* Compact agent workspace toolbar status

* fix: settle workspace reviews after accepted completion (#869)

Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>

---------

Co-authored-by: Laza Bogdan <lazabogdan@users.noreply.github.com>
Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat: Implement Commit & Publish header alignment run 2 (#875)

* feat: Implement Commit & Publish header alignment run 3 (#877)

* feat: Implement Commit & Publish header alignment run 4 (#881)

* test(agents): update stale Band-1 toolbar assertions for M1/M2 disclosure

The header-alignment polish moved the base ref into the branch accessible
name (M1) and made the workspace mode pill borderless (M2), but two
assertions in the AgentsArtifactPane integration suite still expected the
pre-polish visible text and inline border styles.

Assert the base ref via the accessible name and the mode pill via text,
accessible name, and absence of inline border styling, mirroring the
idiom already used in AgentWorkspaceToolbar.test.tsx.

* fix(agents): keep publish sub-tab selection when the pane is already open

Clicking the History, Checks or Automation sub-tabs snapped straight back
to Changes. handlePublishSubTabChange always routed through onOpenPublish(),
which in production resolves to handleOpenPublishPane() with no argument;
its default tab is "changes", so it re-requested the changes sub-tab and
immediately overrode the selection. Review escaped this because
handleOpenReview never calls onOpenPublish.

Only route through onOpenPublish()/onTabChange("publish") when the publish
artifact tab is not already active, matching the existing handleOpenReview
pattern.

Also contain the tab strip at narrow widths (min-w-0 overflow-x-auto) so the
5-tab row scrolls instead of pushing the publish pane into horizontal
overflow. No visual change at normal widths.

Adds a regression test that wires onOpenPublish to the real request loop;
it fails against the unfixed source.

* test(visual): drive publish History tab and refresh publish snapshots

The publish event log moved from the Changes tab into the lazy-mounted
History tab, so the visual spec now activates History via the page object
before asserting on the event log, scoped to the History panel. Adds
History/Automation locators and select helpers to the publish page object.

Regenerates the 13 publish-pane snapshots invalidated by the action-bar and
tab-band restructure; several were silently stale because their diffs sat
within the comparison threshold.

* test(visual): refresh terminal publish history snapshot for the tabbed pane

Merging main re-baselined this snapshot without the publish header
redesign. The diff is confined to the publish pane (action bar reflow plus
the Changes/Review/Checks/History tab band); sidebar, composer, and
terminal are pixel-identical and all functional assertions pass.

* cleanup

---------

Co-authored-by: Laza Bogdan <lazabogdan@users.noreply.github.com>
Co-authored-by: lazabogdan <6580668+lazabogdan@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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