Skip to content

[Feat] Resolve bare issue references (#234, ENG-512) against configured repositories - #722

Merged
daniel-lxs merged 3 commits into
developfrom
feature/router-bare-issue-references
Jul 24, 2026
Merged

[Feat] Resolve bare issue references (#234, ENG-512) against configured repositories#722
daniel-lxs merged 3 commits into
developfrom
feature/router-bare-issue-references

Conversation

@daniel-lxs

@daniel-lxs daniel-lxs commented Jul 23, 2026

Copy link
Copy Markdown
Member

Draft until reviewed — do not merge without Dan's call. Rebased onto develop after #718 and #728 landed; now two commits: bare-reference resolution + a deadline-dispatch fix its new test caught.

What changed

Closes the last gap in the lookup gate: the routing precheck already extracts references like #234, acme/web#42, or ENG-512 into its externalReference field, but nothing acted on it when the message had no pasted URL. Now, when the precheck returns needsExternalLookup=true and URL parsing finds nothing, gatherExternalIssueContext resolves the reference deterministically:

  • ENG-512-style identifiers → Linear get_issue directly.
  • owner/repo#N → fetched only if that repo is in the deployment's configured repositoryNames (case-insensitive match, configured casing wins).
  • Bare #N / N → fans out across the first 5 configured repositories (environment order; issue numbers that don't exist in a repo drop out at fetch time); each result is labeled per repo ([acme/web#234]) so the informed re-route call disambiguates. Smarter candidate selection (routing memory) is a planned follow-up.

Bare references normalize to canonical URLs and run through #718's registry, so fetch-attempt construction (incl. GitHub's issue_readget_issue fallback) stays single-source. Pasted URLs always take precedence over the precheck reference.

Also in this PR (found by its own test)

A fake-timer test for the shared 8s deadline exposed a pre-existing bug from #693: withExternalLookupTimeout received an already-invoked promise, so an exhausted deadline still dispatched the next MCP call and merely never awaited it. The helper now takes a thunk and checks the remaining budget before invoking.

Security posture unchanged

The model proposes reference text only; fetch targets come from a closed candidate set (the deployment's own configured repos / the connected Linear workspace), execution stays in server code under the shared 8s fail-open deadline. No model changes — same routing model as develop.

Tests

105 router tests green: five bare-reference cases (bare Linear id, multi-repo fan-out with per-repo labels, repo-qualified validation incl. unconfigured-repo rejection, seven-repo fan-out capped at five, URL precedence), the deadline-sharing fake-timer test, and an end-to-end Check issue #234 → fetch → phase: 'mcp' case. pnpm knip, tsc --noEmit, format:check clean.

🤖 Generated with Claude Code

@roomote-roomote

roomote-roomote Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

1 issue outstanding. See task

  • packages/cloud-agents/src/server/router/external-issue-context.ts:68-74: Deduplicate configured repositories case-insensitively before applying the five-repository cap. Repositories mapped to multiple environments are fetched repeatedly; five duplicates can consume the whole fan-out and prevent another configured repository from resolving a bare #N reference.

Reviewed e627d99

@daniel-lxs

Copy link
Copy Markdown
Member Author

Added the fake-timer test for the shared 8s deadline — and it caught a real (pre-existing, since #693) bug: withExternalLookupTimeout received an already-invoked promise, so once the deadline was exhausted the next MCP fetch attempt was still dispatched and merely never awaited. The deadline gated waiting, not dispatching. Fixed in e89da82 by making the helper take a thunk and check the remaining budget before invoking. Net behavior change: a hung first fetch no longer fires a second fire-and-forget MCP call after the budget expires. 105 router tests green.

Base automatically changed from feature/external-issue-provider-registry to develop July 23, 2026 16:49
@daniel-lxs
daniel-lxs marked this pull request as draft July 23, 2026 17:08
daniel-lxs and others added 2 commits July 24, 2026 09:09
The routing precheck already extracts references like #234, acme/web#42,
or ENG-512 into externalReference, but nothing acted on it when the
message carried no pasted URL. When the precheck asks for a lookup and
URL parsing finds nothing, the reference now resolves deterministically
against the deployment's own configuration: repo-qualified numbers must
match a configured repository, bare numbers fan out across configured
repositories only when there are at most three (labeled per repo so the
informed re-route can disambiguate), and Linear-style identifiers fetch
directly. Bare references normalize to canonical URLs and reuse the
provider registry, so fetch-attempt construction stays single-source.

The model still never picks fetch targets: it proposes reference text,
code validates against a closed candidate set and executes under the
existing shared 8s fail-open deadline. Pasted URLs take precedence.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…xpires

A new fake-timer test for the shared 8s deadline exposed that
withExternalLookupTimeout received an already-invoked promise, so an
exhausted deadline still fired the next MCP call and merely ignored its
result (pre-existing since #693). The helper now takes a thunk and
checks the remaining budget before dispatching.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daniel-lxs
daniel-lxs force-pushed the feature/router-bare-issue-references branch from e89da82 to 3049854 Compare July 24, 2026 14:10
Per review: on deployments with many configured repositories, a bare
issue number now fans out across the first five (environment order)
rather than resolving to nothing. Non-existent issue numbers drop out
at fetch time, so only real matches reach the informed re-route.
Smarter candidate selection (routing memory) is a future follow-up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daniel-lxs
daniel-lxs marked this pull request as ready for review July 24, 2026 16:07
@daniel-lxs
daniel-lxs merged commit 92b8b1e into develop Jul 24, 2026
16 checks passed
@daniel-lxs
daniel-lxs deleted the feature/router-bare-issue-references branch July 24, 2026 16:14
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