Skip to content

feat: name new threads from linked tickets - #8344

Open
matheustimbo wants to merge 19 commits into
pingdotgg:mainfrom
matheustimbo:feat/ticket-thread-titles
Open

feat: name new threads from linked tickets#8344
matheustimbo wants to merge 19 commits into
pingdotgg:mainfrom
matheustimbo:feat/ticket-thread-titles

Conversation

@matheustimbo

@matheustimbo matheustimbo commented Aug 27, 2026

Copy link
Copy Markdown

What Changed

New threads can adopt the title and identifier of a ticket linked in their first user message. Resolution runs asynchronously after the existing provisional title, and compare-and-set metadata updates ensure that a manual rename always wins.

The server supports GitHub Issues, GitLab Issues, Azure DevOps work items, Bitbucket Cloud issues, Jira Cloud/Data Center, and ClickUp tasks. It prefers local CLIs where available, supports explicit per-project account bindings, stores sensitive credentials outside settings.json, and falls back silently on ambiguous links or lookup failures.

Web/desktop and mobile settings expose the global policy, project overrides, account configuration, custom templates, and connection tests. User and internal documentation are included.

Why

Ticket-driven threads are difficult to scan when the generated title paraphrases the prompt instead of preserving the ticket identifier and canonical title. Resolving metadata at the server boundary keeps local CLI authentication and credentials with the environment while providing consistent behavior to every client.

Proposal and design discussion: #8334

This is intentionally submitted despite being an XXL external feature PR so maintainers can evaluate the complete behavior. I am happy to split it along the boundaries proposed in the discussion.

UI Changes

Before: no ticket-title policy, ticket account management, project binding, or connection-test controls.

After: these controls are available under Settings → Integrations → Ticket providers and in project settings on web/desktop, with a dedicated Ticket providers route on mobile. The full flow was manually verified against the fork from a remote Mac. Automated screenshot capture was unavailable in the collaborative preview, so this PR does not claim the screenshot checklist item.

Validation

  • Typecheck passed in contracts, shared, client-runtime, server, web, and mobile.
  • 232 focused tests passed across parsing, provider routing, account selection, in-flight deduplication, title precedence, settings secrets, migrations, projections, and server settings.
  • Modified-file lint passed with two pre-existing prefer-set-has warnings in ProjectionSnapshotQuery.test.ts.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for UI changes
  • No animation or motion was added

Generated with GPT-5.6-sol through the T3 Code Codex harness.


Note

Medium Risk
Touches orchestration title races, secret persistence for external integrations, and new operate-scoped RPC probes; behavior is heavily tested but the surface area is large.

Overview
Adds ticket-driven thread naming: on a thread’s first turn, the server can look up a single supported ticket link in the user message and asynchronously replace the generated title using environment/project ticket title policy and provider account bindings, with optimistic concurrency (expectedTitle / titleRevision) so manual renames win over late lookups.

Introduces TicketProviderRegistry (resolve + probe), wires it into ProviderCommandReactor and server startup, and authorizes serverProbeTicketProvider. Server settings now persist ticket-provider secrets outside settings.json, support revision-guarded instance updates, and roll back secret writes on failure. Projections gain ticketTitlePolicy, ticketProviderBindings, and thread titleRevision (migrations 44–45).

Mobile gets a Ticket Providers settings route and a large configuration screen (policies, accounts, add/probe/default/disable, per-project overrides) aligned with existing web/desktop controls; main settings adds navigation rows and sheet targets.

Reviewed by Cursor Bugbot for commit 1ea3f7a. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Name new threads from linked tickets via provider registry and title policy

  • Adds a TicketProviderRegistry service that resolves ticket metadata from URLs using VCS process and HTTP clients, with structured errors for no-instance, ambiguous-instance, unsupported-driver, etc.
  • On the first user turn, ProviderCommandReactor may asynchronously replace the generated thread title with a ticket-derived title, gated by optimistic concurrency (expectedTitle, expectedTitleRevision) to avoid clobbering manual renames.
  • Server settings now store ticketTitlePolicy, ticketProviderInstances (with secrets kept outside settings.json), and a ticketProviderInstancesRevision for compare-and-set updates; applyServerSettingsPatch increments the revision on whole-map replacement.
  • Migrations 44 and 45 add ticket_title_policy_json and ticket_provider_bindings_json to projection_projects, and title_revision to projection_threads; projector and snapshot query layers read/write these fields.
  • New web (TicketProviderSettings, ProjectSettingsPanel) and mobile (SettingsTicketProvidersRouteScreen) UI lets users configure ticket title policy and per-provider account bindings; a server.probeTicketProvider RPC checks instance availability.
  • Behavioral Change: thread.meta.update now omits the title field when expectedTitle mismatches the current title or expectedTitleRevision is stale; titleRegeneration is cleared only when a new non-equal title is provided and a regeneration is in progress. Projects and threads in the read model now include the new ticket fields, which may require out-of-tree consumers to update their schemas.

Macroscope summarized 1ea3f7a.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b9f428d4-08a4-47ad-b32c-e2a9ab07a45a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Effect service conventions review: one finding on the new TicketProviderRegistry wiring in apps/server/src/server.ts. The service module itself (tag with inline interface, exported make, layer, dependencies acquired via yield* VcsProcess.VcsProcess / yield* HttpClient.HttpClient, Schema.TaggedErrorClass failure with structured attributes and preserved cause) matches the conventions, and the Layer.succeed uses in tests/harnesses are legitimate test seams.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/server.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changed web settings UI (TicketProviderSettings.tsx, ProjectSettingsPanel.tsx, IntegrationsSettings.tsx, settingsSearch.ts) against the shared settings primitives and environment-scoping rules. Two consistency findings, both in the new/changed lines; everything else (Button/Select/Switch/Dialog/Field usage, SettingResetButton, search catalog entries, and the project-scoped useEnvironmentSettings(selectedCheckout.environmentId) reads) follows the existing contracts.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts Outdated
Comment thread apps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts Outdated
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread packages/shared/src/ticketTitles.ts
Comment thread apps/server/src/serverSettings.ts
Comment thread apps/server/src/serverSettings.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One new consistency issue in the ticket provider settings: the new SettingsSection id collides with the settings-search anchor id rendered inside TicketProviderSettings, so #ticket-providers matches two elements on /settings/integrations.

The two findings reported on the previous revision (hand-rolled instance rows in TicketProviderSettings.tsx, and the checkout-derived inherited label on the group-wide ticket title row in ProjectSettingsPanel.tsx) are unchanged and still apply.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a broad ticket-provider integration across orchestration, persistence, RPC authorization, secret storage, and web/mobile settings, with new external CLI and HTTP behavior on the first-turn path. Its size, user-facing capability, concurrency semantics, and sensitive credential handling require human review.

You can add or adjust custom eligibility rules. Learn more.

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts Outdated
Comment thread packages/contracts/src/ticketProvider.ts Outdated
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread packages/shared/src/ticketTitles.ts
Comment thread packages/shared/src/ticketTitles.ts
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread packages/shared/src/ticketTitles.ts Outdated
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx Outdated
Comment thread packages/shared/src/ticketTitles.ts

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new ticket-title project row: its inherited-default label can misstate the environment default for multi-checkout groups. Everything else in the changed web files (shared SettingsRow/Select/Switch/Button composition, anchor ids, select widths, environment-scoped probe routing) lines up with the existing settings system.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two error-modeling findings in the new TicketProviderRegistry service. Import/module-namespace and dependency-acquisition conventions look correct (make yields VcsProcess/HttpClient from the environment, layer is canonical, Foo["Service"] is used at call sites, and the earlier aliased layer import in server.ts is now a namespace import).

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/ticket/TicketProviderRegistry.ts Outdated
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx Outdated
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changed web settings UI (TicketProviderSettings.tsx, ProjectSettingsPanel.tsx, IntegrationsSettings.tsx, settingsSearch.ts). The earlier findings (hand-rolled instance rows, duplicated ticket-providers anchor id, misleading multi-checkout inherited label) are resolved — instance rows now use SettingsRow, the anchor id lives only on the section, and the project row passes inheritedLabel: "Default (per checkout)".

Two remaining items, both in TicketProviderSettings.tsx: the dialog's Switch has no accessible name, and a failed connection test renders in the same muted tone as a successful one.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding in the ticket title settings: the invalid-template message renders in the same muted status treatment as the success preview. Everything else in the new panel matches the shared settings primitives (SettingsRow, SettingsSection, Select, Input, Switch, Button variants) and the project/environment scoping reads from explicit environment ids.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding in the web settings scope: the ticket title template row rejects invalid input without any invalid affordance. Everything previously flagged (dialog switch name, probe status tone, duplicate ticket-providers id, hand-rolled instance rows, group-wide inherited label) now follows the shared settings contracts.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/web/src/components/settings/ProjectSettingsPanel.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new TicketProviderRegistry probe path; the earlier notes on TicketProviderResolveError.message, the unused invalid-response reason, and the aliased layer import in server.ts are all addressed.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/ticket/TicketProviderRegistry.ts Outdated
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread apps/server/src/ticket/TicketProviderRegistry.ts

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI consistency review of the changed web settings surfaces. One finding: the new Ticket providers section duplicates its heading text and diverges from the shared list-section pattern. The rest of the changed web code (ticket title policy row, instance rows, project checkout binding rows) follows the shared SettingsRow/Select/Switch/Button contracts and scopes its environment reads explicitly.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/server/src/serverSettings.ts
Comment thread apps/mobile/src/features/settings/SettingsTicketProvidersRouteScreen.tsx Outdated
Comment thread apps/server/src/ws.ts
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changed web UI (TicketProviderSettings.tsx, ProjectSettingsPanel.tsx, IntegrationsSettings.tsx, settingsSearch.ts) against the shared settings primitives. Two consistency findings, both in the new TicketProviderSettings.tsx. The earlier duplicate ticket-providers anchor/heading, the destructive probe/template statuses, the inherited-policy label, and the SettingsRow migration for account rows all look resolved.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a92d5fe. Configure here.

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the new ticket-account rows use a bare border-t, which in Tailwind v4 resolves to currentColor rather than the semantic border token, so each row gets a full-contrast foreground hairline instead of the muted divider used everywhere else in the settings tree.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/TicketProviderSettings.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant