Tagout

v3.2.0: create-issue leaves GitHub, and create-pr takes a fix off main

Released 2026-09-26. Four features and four fixes, plus the test and docs commits that rode along.

What we were trying to fix

Three themes.

create-issue refused every repository that was not on GitHub. With the skill on the tracker contract, a GitLab project still stopped at Step 1: tracker.capable answered unsupported because scripts/tracker/gitlab.sh did not exist, and an Azure DevOps project stopped the same way for want of scripts/tracker/azure-devops.sh. Azure DevOps is the host furthest from GitHub: work items instead of issues, tags instead of labels, an HTML description by default, and Markdown in large text fields reachable only through the REST API.

A fix debug-issue committed had no way to become a pull request. Only implement-issue could open one, and create-pr refused the default branch outright. A debug-issue run that committed on main, or left changes uncommitted, ended with an empty recap hand-off.

Two scripts trusted a wrong default. make-worktree.sh hardcoded BASE_BRANCH=main and branched off the local ref without fetching. On phmatray/FormCraft, whose default branch is dev and whose origin has no main, the local main sat at a commit dated 2025-08-08 while origin/dev was at 2026-09-23. A phase-1 worker caught it by hand during an auto-dev run. In the other case, wire-edges.sh kept its own copy of the dry-run message that the GitHub backend’s link verbs already print, and spawned one tracker.sh per edge, each re-resolving the backend.

What we decided

Both backends implement every verb in contract.json’s skills.create-issue (#508 for GitLab through glab api, #509 for Azure DevOps through az devops invoke). A decomposed job on Azure DevOps gets native Parent and Predecessor links.

create-pr becomes the one home for opening a pull request (#636). Step 02 stops refusing the default branch: it refuses [DEBUG- probes, switches to fix/<slug>, and commits leftover changes through guarded-commit.sh. A new guard, skills/create-pr/scripts/rewind-default.sh, puts the local default back on origin/<default>, and only once the pushed branch contains every local commit on it. It ships with a refusal-first golden suite, a CI step and a not_decisions entry.

make-worktree.sh now branches off the remote default branch rather than a hardcoded local main (#678). wire-edges.sh resolves the tracker once and relays the backend’s own dry-run output (#603). The git write gate walks a $(...) or backtick span through one function shared by the unquoted and double-quoted states instead of two hand-kept copies (#602).

The public surfaces now lead with Tagout: the README, the site and the host table put the lifecycle first, tagout-migrate second, and install both plugins (#612). The README also gained a wordmark banner (#679).

What got cut

The backends and the rebrand are each one child of a larger parent (#503 and #610). This release ships the GitLab and Azure DevOps children and the public surfaces, each as its own pull request.

What bit us

docs/methodology.md had drifted from recap.md: once create-pr could take a debug-issue fix, the methodology page no longer matched the recap’s behaviour. #689 and #691 brought the two back into agreement.

The test commits close the other gap. open-pr’s draft flag, base and Closes #N line now run under golden tests (#641), and the BLOCKED_BY pointer text in read-the-plan.md is pinned (#596).