What changed
1. The ticket question comes first
Affects: anyone generating a plan
At the end of plan generation, two questions arrive in a single prompt: "create a tracking issue?" and "what next — implement, review, exit?". The issue was already being created before the next-step choice was acted on, but it was asked second. The order in the prompt now matches the order things happen.
Where you see it: the last prompt of /plan-agent:implementation-plan.
2. A plan shows its ticket
Affects: anyone opening a plan page
A plan's source file can carry an issue: key — written either when the plan was generated from an existing ticket, or when a ticket was created for it. That key was kept in the source and dropped on the way to the HTML page, so a finished plan gave no hint which ticket belonged to it. The page now carries a link in its header, labelled Issue #512, plus a machine-readable plan-issue tag other tools can read.
Where you see it: any plan whose source has issue: <url>. Plans without one are unchanged, down to the byte.
3. Finishing a plan updates the ticket
Affects: anyone marking a plan done — and everyone watching the ticket
Both places that mark a plan completed — the build skill's completion gate and the finalize-plan skill — now act on that link. A summary is written first (plan filename, final status, criteria checked, and every completion-report note verbatim), and then one of two things happens:
- Plan finished — you are asked whether to close the ticket. On yes, it closes with the summary attached.
- Plan came up short and landed back at in progress — the ticket is never closed. The same summary is posted as a comment, so the ticket shows where the work stopped.
Where you see it: /plan-agent:finalize-plan <plan>, /plan-agent:finalize-plan --all, or the completion gate at the end of /plan-agent:build.
Decisions
Ride the existing prototype-link path instead of building new plumbing
Plans already had a source key (prototype:) that becomes a page tag and a header link. The ticket link reuses that exact shape. Both are emitted only when the key exists, so plans without a ticket produce identical output — which is what keeps the existing check that re-renders all 84 committed plans green.
Rejecteda dedicated metadata block on the page, and a ticket badge on the plans gallery — both change output for plans that have no ticket.
Closing asks; commenting does not
Closing a ticket is visible to everyone watching it and changes its state. A comment only adds information, so it needs no question.
Rejectedclosing automatically on completion — the plan's author is not always the ticket's owner.
A plan that lands in progress is never closed, but is still updated
The comment is the honest signal: the ticket stays open, and it now says where the work stopped.
Rejectedsilence, which leaves the ticket looking untouched.
The rule is written into both completion skills, not referenced from one
build and finalize-plan each own "mark this plan completed", and the codebase already flags that the two must be kept consistent by hand. Skills load independently, so a cross-reference would not be read. The test therefore asserts every clause against both files and names whichever one is missing it — landing the rule in only one place is the real failure mode.
A failed tracker command never blocks completion
The plan's status is already decided by the time the ticket is touched, so an unreachable tracker is reported in one line and the plan still completes.
Rejectedtreating an unreachable tracker as a completion failure.
Version bumped as a feature, twice
7.2.0 → 7.3.0 for the rendered link, 7.3.0 → 7.4.0 for the completion behavior. New behavior is a minor bump under this repository's rules.
Learnings
The renderer exists in two copies and a test enforces they match
The canonical one is under scripts/; a bundled copy ships inside the plugin, and a check compares them byte for byte. Editing one and not the other fails with a "re-copy it" message rather than anything about the actual change.
A temp directory name leaked into the output and faked a passing test
The new test created its sandbox with the prefix plan-issue-link-, and the renderer writes project paths into the page — so the assertion "this page contains no plan-issue tag" was matching the directory name instead of the tag. Renaming the prefix fixed it. Any assertion of the form "output does not contain X" is worth checking against the scaffolding that produced the output.
One diverged behavioral baseline was noise
The repository has a check that runs several skills headlessly and compares structural facts about what they wrote. It reported 4 of 5 matching; a full re-run reported 5 of 5, and a third run after the build skill was edited also reported 5 of 5. These runs involve a live model, so a single divergence is worth re-running before it is worth investigating.
Prose line-wrapping broke a literal-string test
Two contract assertions failed only because the phrases they searched for were split across lines in the skill file. The fix was to rewrap the sentences, not to loosen the test — a test that tolerates arbitrary wrapping stops asserting the phrase.