Skip to content

Store and reuse resolved ticket and PR URLs in the branch manifest #783

Description

@williamthorsen

Problem

When a remote ticket or pull request lives on a platform that the agent cannot reconstruct or auto-derive from the branch, it has no way to find it. This is most acute for Jira, whose URLs cannot be rebuilt from a branch-derived key and have no automated fetch. So every invocation that needs the remote ticket or PR must re-specify the full URL:

  • /design-and-plan https://hello.atlassian.net/path/to/ticket
  • /review-branch The ticket is https://hello.atlassian.net/path/to/ticket. The PR is https://hello.atlassian.net/path/to/pull-request.
  • /respond-to-review The ticket is … The PR is …

This repeated copy/paste is a recurring source of friction. (GitHub is less affected — a ticket URL is reconstructable from the issue number and the PR is auto-derivable via gh pr view — but the solution treats all platforms uniformly rather than special-casing the easy ones.)

Context

The per-branch branch manifest (.agents/{sanitized-branch}.branch-manifest.json, gitignored) is produced by the derive-session-context bundle. Today it is a pure-derivation cache: composed deterministically from preferences + branch name + working directory, then cached idempotently (read-if-valid, else recompose-and-write). It holds ticket_id/ticket_ref but no URLs, and has no write path for runtime-resolved values.

Ticket resolution already funnels through a shared reference doc, ticket-source-resolution.md (referenced by design-and-plan, review-branch, review-pr, review-gh-pr, assess-ticket, classify-complexity), but the metadata it resolves is held in working memory only. PR resolution has no equivalent shared doc — it is scattered across review-pr (explicit arg), merge-pr (gh pr view), and create-pr (produces the URL).

A URL becomes "known" at two kinds of moment: when it is resolved (the user supplies it, or it is fetched) and when it is created (create-ticket, create-pr).

Proposed solution

Persist the resolved ticket URL and PR URL in the branch manifest and reuse them on subsequent commands, so a remote URL is supplied at most once per branch. Keep skill coupling minimal by placing the caching behavior at the shared chokepoints rather than in each skill:

  • Single mutation point. The derive-session-context bundle gains a write mode that sets and clears the stored ticket and PR URLs, owning all read-merge-write and validation. The URLs are stored as optional manifest fields, so existing manifests stay valid, the fields never force a recompose, and they are carried forward across any future schema change.
  • Free read-through. Because the stored URLs are emitted in the manifest JSON every skill already reads from the deriver, consumers receive them with no new per-skill read wiring.
  • Shared resolver behavior. The ticket resolver doc gains "prefer a stored URL before reconstructing" and "persist on resolve / clear-and-re-resolve on a failed fetch" steps, inherited by every skill that delegates to it. A parallel PR resolver doc is added and referenced by the PR-aware skills, consolidating today's scattered PR-resolution logic.
  • Producers persist once. The skills that create a ticket or PR record the URL via the mutation point at the moment they already hold it.

Invalidation follows write-through semantics: a user-supplied URL overwrites the stored one; a stored URL that fails to fetch is cleared and re-resolved.

Acceptance criteria

Must have

  • The branch manifest can store a resolved ticket URL and a resolved PR URL as optional fields; manifests lacking these fields remain valid and do not trigger a recompose.
  • The derive-session-context bundle exposes a way to set and clear the stored ticket and PR URLs via a safe read-merge-write against the existing manifest.
  • Stored URLs are emitted in the manifest JSON so consumers receive them without per-skill read wiring.
  • On recompose, any previously stored ticket/PR URLs are carried forward rather than discarded.
  • Ticket-source resolution prefers a stored ticket URL over reconstruction and persists a newly resolved or user-supplied ticket URL.
  • A shared PR-source resolution path exists, prefers a stored PR URL, and persists a newly resolved, user-supplied, or newly created PR URL.
  • The PR-aware skills (review-pr, merge-pr, respond-to-review) resolve the PR through the shared PR-resolution path, so a stored PR URL is actually reused on subsequent commands.
  • Skills that create a ticket or PR (create-ticket, create-pr) persist the resulting URL.
  • A stored URL the agent expects to find but cannot fetch is cleared and re-resolved; a newer user-supplied URL overwrites the stored one.
  • New and modified behavior is covered by tests.
  • Documentation, help text, and the shared resolver docs reflect the new manifest fields, the deriver's write mode, and the prefer-stored/persist/invalidate behavior, including removal of references to any superseded ad-hoc PR-resolution steps.

Metadata

Metadata

Labels

featureAdded or improved external functionalityscope:agents

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions