Skip to content

feat(cos): heal zombie issues — partial-ship hybrid + issue-reconcile task#2242

Merged
atomantic merged 1 commit into
mainfrom
feat/issue-reconcile
Jul 7, 2026
Merged

feat(cos): heal zombie issues — partial-ship hybrid + issue-reconcile task#2242
atomantic merged 1 commit into
mainfrom
feat/issue-reconcile

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Problem

A partially-completed issue became an un-claimable zombie: OPEN + in-progress + assigned, with its PR already merged. The claim queue treats in-progress as "claimed and being worked" and skips it, so the remaining scope is never re-picked and never finished. Live examples caught in the wild: #2220, #2179, #2175 (all healed by hand as part of this work — #2220 closed with follow-up #2241 filed; #2179/#2175 released for re-claim).

Root cause: the completion flow had no partial completion state. /do:next Phase 7 was binary (fully-done → close + unlabel), and the branch reconciler is branch-centric so it never touched the linked issue.

Fix (agent-judged hybrid, applied in two places)

Part A — teach the claim flow to partial-ship (claim-issue / -gitlab / -jira):

  • Phase 5 chooses the PR trailer deliberately — Closes #N for a full ship, Refs #N + a ## Remaining section for a partial one.
  • Phase 7 reconciles the issue: separable remainder → close + file a scoped plan follow-up (Refs #orig); continuation → keep open, post Done ✓ / Remaining ▢, remove in-progress + assignee so the queue re-picks it. JIRA records remaining scope + files a follow-up ticket.
  • Prompt-version discipline: claim-issue 3→4, -gitlab 2→3, -jira 1→2; outgoing bodies preserved verbatim in PREVIOUS_DEFAULT_PROMPTS; integrity snapshot regenerated.

Part B — new issue-reconcile per-app CoS task (sibling to branch-reconcile, disabled by default):

  • server/services/issueReconcile.js — pure classifier + gh/git gatherers. A ZOMBIE is open + in-progress with a linked merged PR and no live claim anywhere (no open PR, no local/remote/CoS claim branch, no active agent). Boundary-safe ref/#num matching (issue-222 never matches inside issue-2220).
  • Deterministic pre-step + dispatch block in cosTaskGenerator.js, parallel to branch-reconcile — perpetual drain with a zombieSignature convergence guard; parks when clean.
  • autoClose toggle (ON default; OFF ⇒ comment + release only). Coordinator dedupes follow-ups via a Refs #orig search so federated peers can't file duplicates.
  • Registered across taskSchedule (interval + MANAGED_AGENT_OPTIONS + description), versions.js, cosValidation allowlist, and the coordinator prompt.

v1 zombie scan is GitHub-only (parks on non-GitHub apps); GitLab/JIRA siblings deferred.

Tests

  • server/services/issueReconcile.test.js — 30 new unit tests (ref/reference matchers, ZOMBIE/LIVE/STALLED classifier, end-to-end reconcile over mocked gh+git, signature, prompt formatting).
  • Full server suite green: 16,859 passed, 20 DB suites skipped. Integrity-snapshot test confirms the prompt-upgrade contract (outgoing bodies preserved, versions bumped).

Design record: docs/plans/2026-07-06-issue-reconcile.md.

https://claude.ai/code/session_013EZAPV4vq8A1ea6TB45kXq

… task

Partially-completed issues were left OPEN + `in-progress` after their PR
merged, so the claim queue (which skips `in-progress`) never re-picked the
remaining scope (e.g. #2220, #2179, #2175). The completion flow was binary
(fully-done → close + unlabel) and the branch reconciler is branch-centric,
so it never touched the linked issue. Two fixes:

- claim-issue / -gitlab / -jira prompts now choose the PR trailer deliberately
  (Closes for a full ship, Refs + a `## Remaining` section for a partial one)
  and Phase 7 reconciles the issue with an agent-judged hybrid: close + file a
  scoped follow-up when the remainder is a separable chunk, else post a
  done/remaining comment + release the `in-progress` claim so the queue re-picks
  it (JIRA records remaining scope + files a follow-up ticket).
- new opt-in per-app `issue-reconcile` CoS task (sibling to branch-reconcile,
  disabled by default): a deterministic gh/git scan finds zombie issues (open +
  in-progress yet with their PR merged and no live claim anywhere) and dispatches
  a coordinator agent that applies the same hybrid, with an `autoClose` toggle
  (OFF ⇒ comment + release only) and follow-up dedup so federated peers can't
  file duplicates. Perpetual drain with a convergence signature.

Prompt-version discipline: claim-issue 3→4, -gitlab 2→3, -jira 1→2, outgoing
bodies preserved verbatim in PREVIOUS_DEFAULT_PROMPTS, integrity snapshot
regenerated. New module server/services/issueReconcile.js + 30 unit tests.

Claude-Session: https://claude.ai/code/session_013EZAPV4vq8A1ea6TB45kXq
@atomantic atomantic merged commit bfca89c into main Jul 7, 2026
2 checks passed
@atomantic atomantic deleted the feat/issue-reconcile branch July 7, 2026 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant