Skip to content

[Bug]: /speckit-taskstoissues dedup matches bare task IDs across features — valid tasks are silently skipped #4271

Open

Description

@jabelk

Version

spec-kit v1.0.1 (.claude/skills/speckit-taskstoissues/SKILL.md, dedup step around the list_issues flow)

Description

Task IDs like T001 are local to one feature's tasks.md and restart from T001 in every feature. The dedup step, however, matches repository issues by task ID without scoping to the current feature: if feature 001-auth already produced an issue titled with T001, then running /speckit-taskstoissues for feature 002-billing sees "T001 exists" and skips creating the issue for billing's T001 — a silent gap in the tracker, in exactly the multi-feature repos this command targets.

This is the inverse of #2968 (which was about creating duplicates): the fix direction there makes the matching aggressive enough to now suppress valid tasks.

Expected behavior

  • Include a stable feature identifier (the NNN-name spec dir) in each created issue's title or a label, and require both the feature identity and the task ID to match before skipping.
  • Re-check for existing feature+task issues immediately before creation so two concurrent invocations don't race the fetch-then-create sequence.

Activity

  1. added 2 commits that reference this issue on Sep 24, 2026
    b6d1c3b
    50fbc4a
  2. github-actions commented on Oct 15, 2026

    @github-actions
    Contributor

    Bug assessment — cross-feature-dedup: Valid · severity high


    Bug Assessment: /speckit-taskstoissues dedup matches bare task IDs across features

    Report (summarized)

    The reporter states that task IDs such as T001 restart for every feature. The taskstoissues deduplication step searches repository issue titles by task ID alone, so an issue created for T001 under one feature can suppress creation of the unrelated T001 under a later feature. The report requests feature-scoped matching and a final pre-create recheck for concurrent invocations. The issue identifies Spec Kit v1.0.1 and the Claude taskstoissues skill, and notes this is the inverse of #2968's duplicate-prevention change.

    Symptom

    When two features both contain the same task ID, running taskstoissues for the second feature can report that the ID already has an issue and skip creating the second feature's issue. Expected behavior is to deduplicate only when both the feature identity and task ID identify the same task.

    Reproduction

    1. Create or use feature directory 001-auth with a tasks.md containing T001, then run taskstoissues and create its issue.
    2. Create or use feature directory 002-billing with a tasks.md containing T001.
    3. Run taskstoissues for 002-billing against the same GitHub repository.
    4. Observe that the existing T001 issue from 001-auth is treated as a match and the billing task is skipped.

    The first two steps and the observed cross-feature setup are supported by the report. Exact command invocation and the task descriptions are [NEEDS CLARIFICATION: not provided in the issue].

    Suspected Code Paths

    • extensions/github/commands/speckit.github.taskstoissues.md:67 — instructs the agent to match issue titles using \bT\d{3,}\b and mark a matching task ID as already having an issue, without requiring the feature directory identity.
    • extensions/github/commands/speckit.github.taskstoissues.md:68 — defines the canonical created title as T001: <description>, which contains no feature identifier and therefore cannot support feature-scoped deduplication.
    • templates/commands/taskstoissues.md:75 — the deprecated core command carries the same bare-ID matching rule.
    • templates/commands/taskstoissues.md:76 — the deprecated core command carries the same feature-less canonical title rule.
    • tests/extensions/github/test_taskstoissues_deprecation.py:55-64 — verifies that deduplication and safety instructions exist, but does not assert that matching is scoped to a feature.

    Root Cause Hypothesis

    The deduplication key is defined as the task ID extracted from an issue title, even though task IDs are only unique within a feature's tasks.md. The issue title format also omits the feature directory, so the command has no stable feature identity to compare. Confidence: high; the current checked-out command instructions explicitly implement both parts of this behavior.

    Proposed Remediation

    Preferred: Include the active feature directory basename (the NNN-name spec directory) in every newly created issue title, for example [002-billing] T001: Create project structure. During deduplication, parse both the feature identity and task ID, and skip only when both match the current feature. Preserve compatibility with pre-existing bare T001: ... issues by treating them as legacy matches only when no feature-prefixed issue for that task exists, or otherwise define a migration policy that avoids creating duplicates during upgrade. Apply the same wording to the bundled GitHub extension and the deprecated core template so generated integrations remain consistent.

    The concurrent fetch-then-create race should be addressed separately or in the same change with an explicit final check immediately before each create operation, subject to the available issue API semantics.

    Files likely to change:

    • extensions/github/commands/speckit.github.taskstoissues.md
    • templates/commands/taskstoissues.md
    • tests/extensions/github/test_taskstoissues_deprecation.py and/or a focused taskstoissues contract test

    Tests to add or update:

    • Assert the canonical title includes a feature identifier and the task ID.
    • Assert the skip rule requires both feature identity and task ID.
    • Cover two features that both contain T001; an issue for feature A must not suppress feature B.
    • Cover rerunning the same feature and compatibility with legacy bare-ID issues.
    • If the race mitigation is implemented, add a deterministic test for the final pre-create recheck or document the API-level limitation.

    Risks & Considerations

    • Existing repositories contain bare-ID issues, so a naive title change can create duplicates during upgrade; the compatibility rule must be explicit and tested.
    • Feature directory names may contain characters that need safe title formatting, and parsing must not accidentally treat task descriptions containing T001 as the task key.
    • The core command is deprecated, but changing both templates is needed to keep older installed integrations behaviorally aligned.
    • A final recheck reduces but may not completely eliminate races unless issue creation is made conditional/atomic by the remote API.
    • No security or data confidentiality impact was indicated; the primary impact is silent loss of issue-tracker coverage.

    Open Questions

    • [NEEDS CLARIFICATION: Should the feature identifier be the complete NNN-name directory basename, a normalized value, or a dedicated GitHub label?]
    • [NEEDS CLARIFICATION: What exact legacy behavior is desired for existing bare-ID issues when no feature identity can be inferred?]
    • [NEEDS CLARIFICATION: Does the issue-write API expose an atomic create-if-not-exists operation, or should the race be documented as a separate follow-up?]

    Generated by 🐛 Assess Bug from Labeled Issue for #4271 · copilot · gpt52codex · 1.81 AIC · ⌖ 0.597 AIC · ⊞ 22.3K · ◷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions