Skip to content

tracker: warren-tracker/v1 requires open/closed/other; the bridge rejects anything else - #1180

Open
PatrickKalkman wants to merge 1 commit into
jayminwest:mainfrom
PatrickKalkman:fix/tracker-status-vocabulary
Open

tracker: warren-tracker/v1 requires open/closed/other; the bridge rejects anything else#1180
PatrickKalkman wants to merge 1 commit into
jayminwest:mainfrom
PatrickKalkman:fix/tracker-status-vocabulary

Conversation

@PatrickKalkman

Copy link
Copy Markdown

Summary

  • The raw-status promise in warren-tracker/v1 does not hold, and it makes every remote tracker unable to finish work. src/tracker/remote/protocol.ts and docs/design/issue-tracker.md tell a server to send its raw status string and promise the bridge normalizes it. The bridge (normalizeIssueStatus, src/core/wire-tracker.ts) only recognizes the literal strings open and closed and folds everything else to other. A remote tracker's Done or Closed therefore never reads as closed: src/plan-runs/create.ts never sees a plan as finished, src/plan-runs/coordinator.ts:241 never skips a finished child on resume, and src/runs/reap/auto-plan-run.ts:145 never fires. extensions/tracker-jira sends the raw Jira status name, so it is broken this way today; the conformance suite accepts any non-empty string, so it never noticed.
  • Fix: the server folds, the bridge rejects. Only the server knows whether its Done, Resolved or Removed is terminal, so the protocol now requires every issue status to be one of open | closed | other. RemoteTracker rejects any other string as a malformed payload (TrackerError: remote tracker returned unknown issue status "Done" for issue X …) instead of silently folding it — a non-conformant server fails loud on its first read rather than never finishing.
  • The conformance suite now enforces it, and adds the semantic check that was missing: after POST /issues/{id}/close, the issue must read closed on both views (issues/close-reads-closed). A new self-test proves the suite fails a server that reports raw statuses.
  • tracker-jira maps statusCategory.keynewopen, indeterminateother, doneclosed, no category → other — the same field it already used to decide whether an issue is terminal.

Changes

  • src/core/wire-tracker.tsnormalizeIssueStatus doc: for in-core trackers only, and why the bridge must not use it.
  • src/tracker/remote/protocol.ts — status fields typed IssueStatus; header text corrected.
  • src/tracker/remote/remote-tracker.tsrequireIssueStatus replaces the fold; three call sites (issue read, status map, scheduled issues).
  • src/tracker/remote/remote-tracker.test.ts — rejection tests for getIssue and listIssueStatuses; fixtures moved onto the vocabulary.
  • src/tracker/conformance-parity.test.ts — header wording.
  • extensions/tracker-conformance/ISSUE_STATUSES/isIssueStatus in the published protocol copy; vocabulary checks on the status map, the issue read, and scheduled issues; the issues/close-reads-closed case; FakeTracker fixture typed; README; self-test for a raw-status server.
  • extensions/tracker-jira/issueStatus() in jira/map.ts, used by the issue read and the search-page status map; JIRA_NEW_CATEGORY; protocol copy; README fold table; tests.
  • docs/design/issue-tracker.md §1 and CHANGELOG.md [Unreleased].

Not in this PR: an optional rawStatus pass-through for display. Easy to add if you want the tracker's own spelling visible in the UI; left out to keep this to the correctness fix.

Test plan

Compatibility

This is a protocol tightening. A third-party warren-tracker/v1 server that sends raw statuses was already non-functional (nothing it reported could ever be closed); after this change it fails on the first read with a message naming the fix. Both shipped servers (tracker-jira, and the ADO tracker for #1173) send the vocabulary.

Relates to #1173.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rf5tbgdUDmHzKnNXpiJLvg

…dge rejects anything else

The protocol text told a server to send its raw status string and
promised the bridge would normalize it, but normalizeIssueStatus only
knows the literal words open and closed and folds the rest to other. A
remote tracker's Done or Closed therefore never read as closed: plan-run
creation never saw a plan as finished, the coordinator never skipped a
finished child on resume, and auto-plan-run detection never fired.
tracker-jira sent the raw Jira status name and was broken this way; the
conformance suite accepted any non-empty string and never noticed.

Only the server knows which of its states are terminal, so the fold is
the server's job. The protocol now requires every issue status to be one
of the three words, RemoteTracker rejects any other string as a
malformed payload, the conformance suite checks the vocabulary and that
a closed issue reads closed, and tracker-jira folds statusCategory.key
(new → open, indeterminate → other, done → closed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rf5tbgdUDmHzKnNXpiJLvg
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-29T02:23:06.230698Z 2c550d8 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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