Conversation
…tup wizard The tracker posted captain's-log comments but never moved the issue, so someone still had to drag the ticket to In Progress, In Review and Done by hand while the workflow already knew each of those moments. tracker.mapping maps workflow events to the team's status names, per workflow, because named workflows need not share stages. Unknown events and stage names are rejected at load; status names are checked during Plan readiness against the team's real workflow states without changing anything. Each transition applies exactly once, in order, across restarts, through the same durable receipts and head-of-line retry the comments use, so a transition waiting to retry holds back later ones and a brief outage cannot leave the issue behind the run. Manual changes are overwritten: the mapping always applies and the last write wins. The issue asked for this to be decided; it is forced rather than chosen, since forward-only would contradict the requirement that a rewind after Done can move the issue back to work. envctl tracker setup writes the mapping. It asks for a credential file path, never the key, which it reads to check and never prints or writes; then the team; then a status for each event from a numbered list of the team's real states, with defaults chosen by the tracker's state type so that accepting every default works. In Progress and In Review share Linear's "started" type, so review is told apart by name and has no fallback: a team without a review state leaves approval unmapped rather than moving a waiting run back into the working state. It previews the transitions a typical run would make, splices the block into envctl.yaml without disturbing anything outside it, edits rather than duplicates on a rerun, and refuses without a terminal instead of hanging. Refs #21 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Owner
Author
|
Rebased onto
While writing those I also checked a suspicion about round 1: Full |
sam-bretz
force-pushed
the
issue-21-tracker-status-map
branch
from
September 16, 2026 16:57
220b872 to
62137c5
Compare
sam-bretz
marked this pull request as ready for review
September 17, 2026 02:59
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #21.
What changed
The tracker posted captain's-log comments but never moved the issue.
tracker.mappingnow maps workflow events to the team's statuses, per workflow, andenvctl tracker setupwrites that mapping from the team's real states.How this was built — please read
The skill's Codex worker built round 1 (mapping config, validation, readiness checks, durable ordered transitions). I built round 2 (the wizard) directly. Three consecutive Codex rounds were SIGTERM'd by the harness's background-task memory guard — the last one within seconds, before writing a single file — so the worker path was not viable. I reviewed round 1 in full before building on it.
Acceptance criteria
Mapping and transitions
tracker.mappingundertracker:; without it statuses never change and the digest is unchangedrun showWizard
envctl tracker setup: tracker, credential file, check, team, status per event from a listenvctl.yaml, re-running editsTwo things I verified rather than assumed
Ordering. My first concern was that a transient failure on "In Progress" followed by "Done" succeeding would let the retry land last, leaving the ticket at In Progress. It can't:
deliverRunis strictly head-of-line — it delivers one pending entry per tick and stops while that entry is in retry backoff. Status entries reuse that existing path.Crash safety. A crash between
SetStatussucceeding and the receipt being frozen replays the call on restart — butSetStatusreads the issue's current state first, so the replay is a no-op.The manual-change policy is forced, not chosen
The issue asked to "decide and document" between forward-only and always-apply. Always apply, last write wins is the only option consistent with the issue's other requirement that a rewind after Done does not silently leave the ticket Done — forward-only would forbid exactly that move. Documented as such.
A bug a test caught in my own defaults
Linear's In Progress and In Review share the
startedtype, so review is distinguished by name. My first version fell back to any started state when no review state existed, so a team without a review column had "Doing" silently mapped as its review state — moving a run waiting for approval back into the working column.TestADefaultIsLeftUnmappedWhenTheTeamHasNoStateOfThatTypecaught it; review now has no fallback.Testing
gofmt -l .silent,go vet ./...clean, fullgo test ./...passes. Wizard tests use a scripted reader and a fake tracker: defaults end to end, the API key never appearing in output orenvctl.yaml(asserted against a sentinel value), declining writes nothing, re-running edits rather than duplicates, comments outside the block survive, a one-linetracker:is refused, and the non-TTY refusal.Not verified against live Linear. The
teamsandstates { type position }queries are new and exercised only through the fake. One realenvctl tracker setupagainst a Linear workspace is worth doing before merge.Known duplication
SpliceTrackerduplicates the comment-preserving splicer ininternal/authoring, which lives on the unmergedweb-compare-commits-and-root-warningbranch and so could not be imported. The two should be unified once that lands.🤖 Generated with Claude Code