pingdotgg / pingdotgg/t3code

[Bug]: Same-name skills from different sources collide and can invoke the wrong skill

Open
#11,161 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accepted bug via-triage
Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

Problem

Two unrelated skills named code-review collide in T3 Code: Matt Pocock's locally installed skill (~/.agents/skills/code-review/SKILL.md) and an official plugin's skill with the same name. Selecting/referencing code-review invoked the official skill instead of Matt's. We worked around it by renaming Matt's skill to standards-and-spec-review.

Reproduction
  1. Install two enabled skills with identical name: code-review but different sources and instructions, one personal and one plugin-provided.
  2. Open the Codex $ skill picker.
  3. Try to select and invoke the personal skill independently of the plugin skill.
Expected

Distinct sources remain distinguishable and independently selectable. The selected skill's exact identity/path is preserved through dispatch, so the picker cannot silently invoke another same-name skill.

Actual and code evidence

Checked local main at c52b8d96e4b34201f19b5e5bb12c6b2a77bfaa9a:

  • packages/client-runtime/src/providerSkills.ts:32: dedupeProviderSkillsByName retains only the first trimmed, case-insensitive name, ignoring source/path.
  • apps/web/src/components/chat/ChatComposer.tsx:2931: selection inserts only $${item.skill.name}.
  • apps/server/src/provider/Layers/CodexSessionRuntime.ts:626: the prompt is sent as a text input, without a structured skill input binding the selected path.

A direct Node invocation of the real deduplication function confirmed that [plugin, personal] retains only the plugin, [personal, plugin] retains only the personal skill, and giving the personal skill a different name retains both. This verifies the picker collision; it does not imply a hardcoded preference for official plugins in the provider.

Related
  • #8043 fixed duplicate menu IDs/highlighting by deduplicating on name, but assumes same-name definitions are interchangeable.
  • #6095 reports missing explicit Codex skill binding.

This report specifically concerns distinct skills from different sources sharing a name. Please preserve stable unique menu identity as well as the selected source when resolving this.

Provider scope

The fix should apply to all T3 Code providers: Codex, Claude Code, Cursor, Grok, OpenCode, and Antigravity. The original reproduction used Codex, but both source-aware discovery/selection and exact-source dispatch must be preserved across providers and web/desktop/mobile clients.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/client-runtime/src/providerSkills.ts and its dedupeProviderSkillsByName behavior, then trace selection in apps/web/src/components/chat/ChatComposer.tsx and dispatch in apps/server/src/provider/Layers/CodexSessionRuntime.ts. Reproduce the direct Node deduplication check with same-name skills from different sources; done when distinct source/path identities remain selectable and the selected source is preserved through dispatch across the listed providers and clients.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
full-stack, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.