Skip to content

UX:Optimize Revision Workflow: Update Existing Tickets Instead of Recreating Them #91

Description

@ekuris-redhat

Summary

When a revision is requested on generated tickets (Epics, Features, or Tasks), Forge deletes all previously created tickets and regenerates the entire hierarchy from scratch. This wastes tokens, increases latency, and loses history on tickets that didn't need changes.

Expected Behavior

When a user posts a revision comment (e.g., "Add an Epic for X" or "Remove Task Y"), Forge should perform delta updates on the existing ticket structure:

  • Edit existing tickets whose content needs to change (update summary/description in place)
  • Create only genuinely new tickets
  • Archive only tickets explicitly removed by the revision
  • Leave unchanged tickets that aren't affected by the feedback

Current Behavior

  1. Trigger: User posts a comment requesting a modification at any level (Epic, Feature, or Task)
  2. Action: Forge calls archive_issue() on ALL existing tickets at that level, clears the state's key list, then calls the generation function which creates entirely new Jira tickets
  3. Result:
    • All prior ticket keys are replaced with new ones (new AISOS-XXXX numbers)
    • Token consumption is multiplied — the LLM regenerates content for tickets that didn't need changes
    • Processing time increases significantly (full regeneration instead of targeted edit)
    • Ticket history, comments, and metadata on unchanged tickets are lost
    • Archived tickets remain visible as Epic children because parent unlinking silently fails in some Jira configurations

Root Cause

In src/forge/workflow/nodes/task_generation.py (regenerate_all_tasks, line 442):

# Archives ALL existing tasks, then creates ALL new ones
for task_key in existing_tasks:
    await jira.archive_issue(task_key, archive_subtasks=False)

updated_state = {**state, "task_keys": [], "tasks_by_repo": {}}
return await generate_tasks(updated_state)  # Creates brand new tickets

The same pattern exists in epic decomposition (regenerate_all_epics). The regeneration functions treat every revision as a full teardown-and-rebuild rather than a targeted edit.

Scope

This affects all ticket generation levels:

  • Epic decompositionregenerate_all_epics in epic_decomposition.py
  • Task generationregenerate_all_tasks in task_generation.py
  • Single-ticket updatesupdate_single_task / update_single_epic exist but are not used for Feature-level revision feedback

Proposed Approach

  1. Pass existing ticket keys and their current content to the LLM agent alongside the revision feedback
  2. Have the agent return a delta: which tickets to edit, which to create, which to remove
  3. Apply the delta: jira.edit_issue() for edits, jira.create_task() for new tickets, jira.archive_issue() only for explicitly removed tickets
  4. Preserve the original ticket keys in state for unchanged/edited tickets

Impact

  • Token savings: Only regenerate content for affected tickets (often 1-2 out of 5-10)
  • Latency: Targeted edits complete faster than full regeneration
  • History preservation: Unchanged tickets keep their key, comments, and metadata
  • Cleaner Jira: No orphaned archived tickets cluttering epic children

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions