Skip to content

[factory] Cross-surface reopen cannot clear a terminal lifecycle on GitHub ingestion #334

Description

@khaliqgant

Follow-up from #329 (#211), reported by review on that PR.

Once dispatch claims are keyed on the work unit, a run completed through one
surface leaves a terminal row that the SAME unit arriving through the other
surface must be able to reopen. #329 made the reopen scan in
#recordCanonicalIssueState match on work-unit identity, which fixes the
direction where the reopen arrives as a Linear issue.

The originally reported direction is still broken, for two reasons that both
predate the key change:

  1. #recordCanonicalIssueState is only called when issueSource === 'linear'
    (src/orchestrator/factory.ts, in the ready-issue read loop). GitHub
    ingestion never records canonical state, so the reopen cleanup is never
    reached at all on a GitHub-sourced Factory.
  2. reopenedFromTerminal is derived from issueStateKey(issue), which is
    surface-scoped. A GitHub-native ref therefore cannot see a Linear mirror's
    canonical-state entry even when both describe one work unit.

Consequence: a work unit completed through a Linear mirror, then reopened
GitHub-native, hits the terminal row and is refused with
dispatch lifecycle already terminal. #329 reproduced exactly that skip reason
while developing the fix.

Fixing it means giving GitHub ingestion canonical-state recording and making the
reopen gate work-unit scoped rather than surface scoped. That is a real change to
an ingestion path #329 does not otherwise touch, which is why it was filed rather
than folded in.

Worth deciding alongside: whether canonical state should be keyed per surface at
all once claims are keyed per work unit, or whether the two should share the
identity. Splitting them is what makes this reachable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions