Repository navigation
Releases: ToRvaLDz/trailhead
Release list
0.15.0
Why
This release comes from running the engine on real tickets: the engine agents now work inside hard boundaries and hand back reports the engine can read, the shell guards stop tripping on harmless commands while catching wrapped installs, and acceptance testing gets a stale-base preflight, a configurable setup step and a skip option. On Claude Code, the map panel learns about paused tickets, pending UAT, per-map counts and the whiteboard.
Added
- Dashboard view in the map panel (#264). A
Whiteboardrow above the maps list, with itsN open / Mcounts (name-only when they cannot be read), shows the repo index in place of a map: a link to the pinnedtrailhead:dashboardissue, every open map (a click opens it) and the whiteboard's open tickets as Frontier / In progress / Blocked with aworkbutton per frontier ticket.mapgoes back, the mode survives/clear, and the old headerdashboardbutton is gone. - Open and total counts per map in the panel (#260). The maps list shows
N open / Mnext to every map, read in one GraphQL call, and the whiteboard heading readsWhiteboard · N open · M assigned. A failed counts read falls back to names only, never an error. trailhead:uatlabel and a UAT group in the panel (#261). Pending UAT follow-ups carry the newtrailhead:uatmarker label (a marker, never a frontier filter) and show in the panel as their own UAT group with atests <parent> #<n>line and aworkbutton. A newtemplates/trailhead-uat-backfill.jstags existing follow-ups that have aUAT of:line, at first-use setup and once per clone at work-start.- Paused group and "this session" mark in the panel (#259).
/trailhead:pausenow adds atrailhead:pausedlabel,/trailhead:resumeor a new claim removes it, and the panel lists such tickets underPaused · nwith noworkbutton. The ticket your own session is working is marked▸+this session, even when another session in the same checkout overwrites the shared work state file. isolation.copycopies gitignored files into new workspaces (#242). A worktree or clone created for a ticket now receives the gitignored files named inisolation.copy(for example.env.local) before any install, throughtemplates/trailhead-isolation-copy.js. It never overwrites, rejects unsafe paths, and when the key is unset suggests candidates from tracked*.example/*.samplefiles and offers once to save the key.- Stale-base preflight with
preflight.checks(#243). Before UAT and before integration,templates/trailhead-base-preflight.jsmeasures how far the working base is behind the trunk, syncs it, re-runs the tests and runs the commands listed inpreflight.checks(for example a migration-timestamp check). It stops on a conflict or a failing check and fails closed on anything it cannot verify. - UAT setup from project config,
uat.setupanduat.accounts(#252). Acceptance testing now prepares the environment before the drive-mode ask, running the steps inuat.setupthroughtemplates/trailhead-uat-setup.js: a step whosecheckpasses is skipped, a failure stops with a redacted output tail, and--from/--onlyresume. Test accounts are named inuat.accountsby environment variable only, never by value; an unconfigured project is offered a probe-and-save path, andautoruns configured setup only. - Resolve bookkeeping helpers (#253). Two new templates do the mechanical part of Resolve:
trailhead-issue-body.jsedits one section of an issue body (append/replace/remove) with retry, concurrency and secret checks, andtrailhead-dashboard.jsregenerates the pinned dashboard.trailhead-work-state.js clearnow also removes thesession-ticketmarker. - Structured return report from every engine agent (#249). Implementing agents report
status: done | partial | blockedwithcommits:,tests:,deviations:andblockers:; investigating agents reportfound | inconclusive | needs_inputwithanswer:,evidence:andopen questions:; the plan agent reportsready | needs_input. The engine checks the fields (and thatcommits:matches theRefs:set) before it branches, and research findings are posted as aRESEARCHcomment instead of a branch.
Changed
- A paused ticket is off the frontier on every surface (#263). A ticket carrying
trailhead:pausedis excluded from every frontier query (map, scoped map, whiteboard and the dashboard count), so bare/trailhead:workand an autonomous run never pick it;/trailhead:resume, or an explicitwork <n>/quick <n>, takes it back. The map and whiteboard renders and the pinned dashboard gain a Paused group matching the panel: a paused ticket shows once, under Paused, whatever its assignee or blocked state (the dashboard now classifies unverified, then paused, blocked, in progress, frontier, like the panel). - The acceptance testing ask gains a skip option (#254). The drive-mode ask now offers skip next to AI-driven and human-driven, at all three UAT start paths. A skip is a waiver, not a deferral: the
VERIFYcomment recordsacceptance: waived by the user (unconfirmed), never a pass; no UAT follow-up is opened, the Pending-UAT guard does not fire and the resolution comment states the waiver (aUAT of:follow-up closes as waived). The delegate option andautonever pick skip. When no step is agent-performable the ask is no longer skipped outright: it drops only the AI-driven option and asks human-driven or skip, with the one-line reason. AI-driven UAT now also drives a connected phone, emulator, simulator, TV or desktop app. - The ticket-start scope confirm is a menu (#234).
workandquickask it as a picker: Proceed (recommended), Change something, plus the delegate option. A change that diverges from the ticket gets a second menu, work as-is or open a separate ticket. On Codex the same options render as a numbered list. - The scope confirm is skipped on a ticket you just shaped (#244). A ticket this session created from your own request, or one a grilling round just concluded on, gets a one-line note instead of the menu. Tickets from an earlier session, someone else's, resumed or bulk-created still ask, and
autois unchanged. - Isolation answer is remembered (#245). Under
isolation: autothe answer to the work-start concurrency ask is kept in the gitignored.trailhead/isolation-answer.jsonand reused with a one-line note while the other assigned tickets are the same and the last work-start was under 8 hours ago./trailhead:autoand explicit modes never use it. bug --ofinherits the origin's destination (#246). A regression bug lands on the origin ticket's open map, or on the whiteboard when the origin is there, without the which-map ask. A closed origin map or a failed lookup falls back to the usual rule.- Engine agents carry hard git and tracker boundaries (#248). Every
trailhead-*agent forbidsgit push,git stash,git reset --hard,git checkout -- <path>,git clean -f, branch switches and tracker writes (the orchestrator posts), and leaves other sessions' changes in a shared checkout untouched. Executor and fix agents compare against the baseline SHA in a temporary worktree instead of stashing, and commit by path. - Verify and code review open with a fixed status line (#250). Review agents return their report instead of posting it, and
templates/trailhead-report-status.jschecks the first line (met/gaps_found/inconclusive, orclean/issues_foundwith a counts line), rewrites an equivalent spelling and asks the agent once to redo an ambiguous one. A second failure stops at a checkpoint instead of guessing a verdict. The shared agent text now lives inscripts/agent-blocks.md, synced byscripts/sync-agent-blocks.js. - The Execute step is split into orchestrator and executor parts (#251). The implementing protocol lives in
references/executor-brief.md, the only protocol text given to the executor and fix agents, so they no longer carry orchestration steps such as branch, PR and fidelity posting.
Fixed
- Shared core loads by absolute path (#237). The skills load the shared core with the Read tool on absolute paths resolved from the skill's base directory, instead of
cd ... && catrelative reads that the search guard denied. The Codex adapter resolves skill references the same way. - Search guard no longer reads redirections as file reads (#238).
>,2>/dev/null,&>and heredoc operators with their targets are skipped, and acdinto the session's own working directory no longer arms the check. Acdto a real other directory still does. - Install guard no longer flags lockfile installs or text inside
echo(#239). Commands are split with the quote- and heredoc-aware scanner, redirections are ignored, and--filter/-Fvalues are no longer read as packages. A lockfile flag still does not exempt a line that names a package. - Install guard sees wrapped installs and file-like package names (#255, #258). An install behind
sudo,time,env,nohup,xargs,timeout,nice,stdbuf,setsid,ionice,doas,commandorexec(including nested chains andenv -Spayloads) is now gated. A name such asleft-pad.tomlis local only when it is a path or exists on disk. - Commit-msg hook no longer aborts every commit in
"type": "module"repos (#257). The hook is now a POSIXshwrapper running a.cjsfile beside it, so the repo'spackage.jsoncannot change its module format. The sync installs both files and migrates the old single-file hook. - Commit-msg hook warns when it cannot enforce (#262). If the
.cjsis missing, node is not on PATH or the logic crashes, it printstrailhead: commit-msg hook inactive (<reason>); commit rules not enforced.and lets the commit through. A rule violation still blocks. - **Dashboard regeneration works on a fu...
0.14.0
Why
On Claude Code, trailhead now draws the work on screen while you work instead of only in the transcript: which ticket is in play and at what step, the active map's tickets with a button to work one, and how the map is burning down. It arrives as a mod (a Claude Code function-hooks module) that ships inside the plugin next to the command hooks, so the command hooks stay the floor on Codex and on builds without mods. This release also hardens the shell guards against many ways of hiding a secret, a secret read or an empty body from them.
Added
- The trailhead mod (Claude Code 2.1.287+, plugin install) (#202).
hooks/mod/register.tsx, declared undermodulesinhooks/hooks.jsonbeside the command hooks; a Claude Code build without mods skips only the module. Typed state contract intypes/index.d.ts;npm testnow runs every suite plusclaude plugin validate/claude plugin test. The npm installer and the Codex projection do not ship it yet: on those installs nothing changes. - Work state file (#205). The skills write
.trailhead/work-state.json(map, ticket, title, step, auto run, session) throughtemplates/trailhead-work-state.jsat work-start, at every step, on pause/resume and inauto, and clear it at Resolve. It is gitignored local state; the mod only reads it, and a file from another session shows as orphaned (dimmed, never deleted). - Status entry and pipeline band (#203). A
trailhead:status entry (map #n · #t title · step) under the prompt and a band above it with the ticket and thediscuss › plan › execute › verifypipeline (auto · n doneduring an autonomous run,‖ paused, dim when orphaned). - Work state in the system prompt (#204). A short
trailhead:work-statesection (map, ticket with its link, step) is added to the system prompt at session start and after a compaction, rebuilt only on a ticket change so step changes keep the prompt cache; absent when orphaned. - Live map panel,
/trailhead:panel(#208). A pane listing the active map's open tickets as Frontier / In progress / Blocked, with holders, the ticket in play marked▸, and aworkbutton per frontier ticket. It reads the tracker throughghonly while open (15 s floor), keeps the last list with a dim reason whenghfails, opens by itself once in fullscreen, and/trailhead:paneltoggles it. - Burn-down in the map panel (#228). Open tickets over time from the map's first ticket to now (
open · done · removed · peak; superseded and out-of-scope closes count as removed scope): a 3-row chart on the terminal, a sparkline on the desktop app; a failed read keeps the last curve with its age. - Switch maps from the panel (#229). With more than one open map, a
Maps · nlist (active map marked●); a click only views another map (viewing #n · active #m,back to active). The active map changes on use: working a named map ticket makes its map the active one (rule in_shared/multi-map.md). - Panel through
/clear, clear before work (#230). The band and the panel restore their state after/clear; theworkbutton runs/clearand then/trailhead:work <n>, so each ticket starts on a clean context. - Close button in the panel footer (#231).
refreshand the status on the left,closeon the right; a status too long beside the buttons moves to a row of its own.closecounts as closing it by hand (no auto-open again that session). - Screenshots of the panels (#232). README (EN/IT), the
/trailhead:paneldocs page and a new Live in Claude Code section of the website landing show the map panel, map switching, the burn-down and the band, taken from the approved mockups.
Changed
- Secret, body and secret-read guards fail closed on constructs they cannot interpret (#227).
eval,source/., a bash 5.3 function substitution (${ cmd; },${| cmd; }),printf -v, a function definition, an alias, agh apibody field written with a quoted or split key (-f 'body'=,-f bo""dy=) and a backslash-newline inside a word used to be emulated case by case; the gaps (echo ${ gh issue comment ... },alias g=gh; g issue comment ...,source ./post.shbefore a write, a quoted api key in the body guard) let a write through unchecked. They are now a closed list the guards do not emulate: a final gate, after every existing verdict, blocks withSECRET_GUARD_UNMODELLED_CONSTRUCT,BODY_GUARD_UNMODELLED_CONSTRUCTorSECRET_READ_UNMODELLED_CONSTRUCTand a message asking for the simple form (its sample is truncated and redacted). A hit blocks only when it can matter to that guard: the code it hides or the function / alias it defines (when called) holds a write, a write that can depend on them followssource/printf -v(it has an expansion, a~or a relative path; a fully literal write passes), its own statement is a write, or (read guard) a secret-looking piece sits next to it;alias ll='ls -l',source ~/.venv/bin/activate && pytest,eval "$(ssh-agent)"and the same words inside quoted prose or a comment pass. Supersedes #221 and #224 (individual cases of the same gap). The shipped hook libs now includeunmodelled.js. - The five Bash guards run in one hook process (#207). The commit, secret, install, search, and body guards used to be five
PreToolUse(Bash)registrations, so every Bash call started five node processes. They now share one,trailhead-bash-guards.js, which evaluates them in the same order with unchanged verdicts: the first block wins, a guard that errors allows on its own without stopping the others, and a guard module that cannot load is skipped with a stderr warning and a session advisory naming it. The guardrails themselves are unchanged (still the same set of distinct protections); only the registrations and process spawns shrink, to three hook processes per Bash call on Claude Code and Codex. On Codex the hook is registered with--guards=commit,secret,install,body(no search guard). A freshTRAILHEAD_MOD_GUARDS=<name,...>@<epoch-ms>stamp, set by the mod for guards it already ran, makes the hook skip exactly those; a missing, malformed, or stale stamp skips none. - Installs migrate on their own. Re-running the installer strips the old per-guard registrations from
settings.json/hooks.jsonand registers the merged hook; uninstall removes the merged entry and any legacy one. Install-verify now separates the shipped files (the five guard modules are still copied) from the registered entrypoints.
Fixed
- Mockup-link guard accepts an approval question that carries the link (#209). Claude Code writes the assistant message to the transcript only after the tool call, so the guard never saw the prose with the mockup link and blocked every approval ask. It now accepts a link in the question, header or options, and judges the prose only when it can find the pending ask in the transcript.
- Secret guard follows a body file passed through a shell variable (#210).
--body-file "$D/x.md"was read verbatim and missed; writes behind another statement (D=... && gh ...,cd x && gh ...) were not seen as writes. Every statement of a compound command is now analysed and body sources (files, stdin, heredocs, inline bodies,gh apifields) are resolved with shell semantics. - Body guard sees an empty-body write chained after another command (#211). It now walks every statement like the secret guard; on a partial install it falls back to the single-statement check instead of allowing everything.
- Shell scan no longer reads
<<in arithmetic or quotes as a heredoc (#212). A fake heredoc used to swallow every later line, hiding e.g.cat .envfrom the guards. One context-aware lexer (quotes,$((..)),${..},$(..), comments, escapes, continuations) now drives the heredoc walk and the statement splitters. - Guards see a gh write with a flag between the subcommand and the verb (#225).
gh issue -R o/r comment 5 --body <T>,gh pr --repo o/r comment 5 ...,gh issue --repo=o/r comment 5 ...andgh issue -R o/r edit 5 --body ""slipped past the secret and empty-body guards because the shared parser read the flag as the verb. Flags after the subcommand are now skipped with the same arity model as the global ones, so the real verb is classified. - Secret-read guard sees a heredoc fed to a shell interpreter (#223).
bash <<'EOF',sh <<EOFandcat <<EOF | bashwithcat .envin the body slipped past because a heredoc body was only ever data, and only the substitutions in an unquoted one were scanned. A body whose pipeline runsbash,sh,zsh,dashorksh(also behindNAME=valueorenv, with any flags or path) is now scanned as commands, whatever the delimiter quoting.cat <<'EOF',tee f <<'EOF'andcat <<EOF; bash x.shstay data, and wrappers such assudoornohupare not followed. - Secret-read guard sees a secret path split by a line continuation (#222).
cat \<nl>.env,echo $(cat \<nl>.env)andcat .e\<nl>nvslipped past because the statement splitter rejoined the lines with the backslash and a newline still in place, so the path token never matched. A live backslash-newline is now removed like bash does, in the splitter shared by the guards. A single-quoted continuation and an escaped backslash before the newline stay literal. - Secret guard sees a token rebuilt by brace expansion (#220). A credential written with an unquoted brace group (
--body <A>{,x}<B>,"<A>"{,x}"<B>",<A>{x,}<B>,x{<A>,y}<B>, or agh api -f body=<A>{,x}<B>field) slipped past because the guard read{,,and}literally while bash expands the word into<A><B> <A>x<B>before gh posts it. The guard now expands brace groups on the raw word like bash (comma lists, nesting, several groups,{x..y}and{x..y..step}sequences) before quote removal, both when it scans the statement words and when it traces a--body,-b,gh apifield, echo/...
v0.13.0
Why
Anthropic is retiring the standalone Claude Design site: claude.ai/design closes on 2026-12-14, and Claude Design now lives inside Claude, where new designs, design systems and decks are Artifacts. trailhead's hosted mockup mode was built on that site (canvases made by hand or with /design, design systems driven through the claude-design MCP and DesignSync), so it had to move before the site goes away. Artifacts also make the flow simpler: Claude Code already ships the Artifact tool, so there is nothing to install and no separate login, the canvas is shareable and commentable like any other artifact, and DesignSync, which is now meant only for the user-started /design-sync skill and explicitly not for making designs, drops out of trailhead entirely.
Changed
- UI mockups move to Claude Artifacts (
design: artifacts). The Prototype technique builds each mockup as a Design canvas Artifact through Claude Code's built-inArtifacttool: one canvas per map (picked, pasted or created, cached indesign.project), one artboard per screen or variant grouped in a canvas page per ticket, and the design system named by the newdesign.systemkey (or the account's default) installed on the canvas so its tokens and components are at hand. Approval asks carry the canvas URL plus each artboard's name, and the approved artboards are re-read before any UI code. Screens are never pushed into a design system any more, so the DesignSync path, its MCP install offer and its manifest rules are gone;design.surfacenow applies tostitchonly. - Legacy
claude.ai/designconfig keeps working. It is read asartifactswith a one-time notice and an offer to rewrite the key. A cached claude.ai/design project id can't be reused (standalone projects don't migrate on their own), so at the next mockup trailhead offers first the canvases and design systems whose name matches the repo, then the usual pick / paste / create, and drops the legacydesign.surfacewhen it writes the new keys. Where theArtifacttool is missing (Codex, API-key sessions) it offersstitchbefore falling to local disk. - Website (site only; not part of the npm package). A new Design mockups guide explains the Artifacts, Stitch and disk flows, the fallbacks, and the step-by-step migration from claude.ai/design (design systems from the Artifacts page banner, project archives, chats and comments, organization settings); the Configuration page now summarises the
designkeys and links to it.
v0.12.1
Changed / Fixed
- Label guard filters at job level. The shipped
trailhead-label-guard.ymlnow skips the job with a job-levelif:(atrailhead:label, a sender other than the repo owner, not inTRAILHEAD_LABEL_ALLOWLIST) instead of returning early from the script. A skipped job is not billed, while every started one costs at least one Actions minute, so the old guard ran into thousands of billed runs a month on a repo trailhead labels all the time. The in-script permission check is unchanged and stays the real defence. - Outdated guards are migrated. A new
templates/trailhead-label-guard-sync.jsclassifies a repo's guard (absent/current/outdated/custom/foreign) and, with--apply, installs or upgrades it from the template, never touching a foreign or customised workflow. The first-use setup (chart/adopt) and/trailhead:updaterun it and offer the upgrade when the committed guard lacks the job-levelif:. - Session-start label guard check. Like the pinned-model review, the SessionStart hook (or the load-first check on a host with no hook bus) offers to upgrade an outdated guard in the current repo, every session until you answer; the answer is stored in the gitignored
.trailhead/label-guard-ackand the offer returns only if the guard file changes. - Website (site only; not part of the npm package).
/docsgained a guide per verb cluster (chart, work, view, capture, manage) with a sidebar group, the commands page became an index linking them, the configuration page documents model profiles, tier defaults and the pinned model review, and a hooks page covers the session-start check and the commit-msg hook. Site CI now checks cross-page fragments and the site's own canonical URLs against the fresh build. This repo's own label guard already carries the job-level filter.
v0.12.0
Added
/trailhead:audit [map] [--all](#190, #192). A new manage-cluster verb that hunts regressions: it checks that the tickets closed since the last audit (a<!-- trailhead:last-audit -->marker in the pinned dashboard, preserved across regenerations; the first run covers the whole history) are still true against the current code. A deterministic fast path (no agent) compares the lines abuild/bugticket'sRefs:commits touched with HEAD and classes untouched ones as unchanged; decisions, research, tasks and prototypes get a light inline check of their recorded answer or outcome; the full verification agent runs only on tickets whose code changed or that have noRefs:commits. A ticket whose lines were later changed by another ticket's commits is classed evolved (listed, no proposal); the rest is implemented, implemented wrong, or not implemented. It also compares open tickets for duplicates and groupable clusters. Read-only until you confirm: each fix (abug --ofregression ticket, a reopen, a native duplicate close with the wiring carried over, a supersede-and-merge) and the marker advance are separate proposals applied only on an explicit yes.- Audit walk script (#193). The audit's fast path and attribution walk run as a tested, dependency-free script,
templates/trailhead-audit-walk.js(index/fastpath/attribute, JSON out), shipped on every host; the audit protocol points at it and stays the spec. - Mockup-link guard hook. A
PreToolUse(AskUserQuestion)hook blocks a mockup approval ask (or a pick between mockup variants) when the reply text right before it has no URL or file path, so the agent writes the clickable link and asks again. The prose rule alone was still skipped in practice (an approval asked with only the project's name). On Codex, where a question is a plain-text numbered list, its twinmockup-link-stopruns as aStophook: a final reply that asks for the approval without a link continues the turn so the agent adds it.
Changed / Fixed
- Haiku 5.5 by default (#194). The fast model tier now resolves to
claude-haiku-5-5; a config pinningclaude-haiku-4-5-20251001orclaude-haiku-4-5gets the pinned-model review offer, and the Manual menus offerclaude-haiku-5-5/claude-haiku-4-5. - Codex verb skills quote their description once (#191). Command frontmatter values are unquoted before projection, like the agent ones.
- Secret-read guard allows name-only operands and templates. Operands that only name a file (
git check-ignore/ls-files/rm --cachedpathspecs, the destination of a one-sourcecp/mv) and templates such as.env.exampleno longer trip the guard; the<rev>:<path>form (git show HEAD:.env) is now caught. - Command templates label the user's arguments. Every
/trailhead:<verb>template marks the typed arguments as data, never instructions; thequickdescription is quoted so its frontmatter is valid YAML. - commit-msg hook sync fallback. The work start tries all three template directories before reporting the sync script missing.
- Ticket numbers stay visible. Every ticket is rendered as its name with its number in sight, never hidden inside a link.
- Mockup approval stays in prose. The mockup link is written in the reply and the approval is a plain yes/no ask.
- Links before any menu.
choices.mdnow states, for everyAskUserQuestiontrailhead authors, that anything the user must open first has its clickable link in the reply text right before the menu; the Prototype rule adds that a project's name is not a link.
v0.11.1
Added
- Pinned-model review (#186, #187, #188). When a
models.*ormodels.codex.*value pinned in the config is older than the current tier default, trailhead offers to review it, once per project per defaults change. It reads the effective config (global merged under project, project wins key by key), names the config file each stale pin came from, and surfaces from both the SessionStart hook and the skill's config load. The offer stays until the user answers it: the check is read-only and an explicit ack records the choice. - Run reviews until they converge. When Cross-AI plan review or Code review exhausts its rounds with blocking findings still open, the checkpoint now also offers to keep the revise/fix and re-review loop going with no round cap until nothing blocking remains. A no-progress guard (the same blockers coming back unresolved) stops the loop and brings the choice back to the checkpoint.
Changed / Fixed
- SessionStart hook never hangs on stdin (#186). The hook input is read asynchronously with a timeout and skipped on a TTY, instead of a synchronous read that could block forever.
- commit-msg hook fallback (#189). When the hook sync script is missing, the work start inspects the hooks directory itself and accepts only an executable trailhead commit-msg hook.
- Mockup link next to the approval ask. The prototype mockup link now sits in the same message that asks for approval.
quickdescribed as the lighter path. Capture confirmations and the session handoff describequick <n>by its purpose (always size-triaged, offers to skip the heavy steps on a small change, no map book-keeping), not just as the no-split alternative.
v0.11.0
Added
- Code review records every finding's fate (#183). Each finding gets a stable ID (
C1,W1,I1) kept across review rounds; theVERIFYcomment carries a cumulativecritical: <n> · warning: <n> · info: <n>counts line understatus:and a findings ledger with one disposition per finding (fixed,deferred → <ticket>,accepted: <reason>). A disposition gate in both the build and bug Resolve steps blocks the close while any finding is stillopen, so Warnings and Info no longer evaporate. - Refs trailer enforced by the commit-msg hook (#184). While
.trailhead/session-ticketnames a ticket, the git commit-msg hook rejects a commit without itsRefs: #<n>trailer, with a clear message; commits made with no marker are unaffected and a malformed marker never blocks. - commit-msg hook kept current (#185). A self-contained sync script, run at chart/adopt and at every work/quick start, installs the hook when absent, upgrades an older trailhead hook in place, and never touches a foreign one (reported instead); it follows
core.hooksPathand linked worktrees. - The installer verifies the install (#182).
--claudeand--codexinstalls check every clusterSKILL.md, the_shared/core, the hook scripts and targets, and thetrailhead-*agents before printing✓; a broken install prints✗ … missing: <entry>and exits 1, and a reinstall no longer leaves a stale hook file behind.
Changed / Fixed
- Opus 5.5 and Sonnet 5.5 by default. The strong model tier now resolves to
claude-opus-5-5and the standard tier toclaude-sonnet-5-5, so the Balanced profile plans on Opus 5.5 and executes on Sonnet 5.5; the Manual menus offer the two latest versions of each family. - Review and verification scoped to the ticket's own commits (#181). Code review and goal-backward verification read the commits carrying the ticket's
Refs: #<n>trailer, one by one, instead of a<base>...HEADrange that swept in other tickets' commits; an empty set is an error and the set is recomputed each round. - Secret-read guard allows
--env-file(#180).docker/podman(and theircomposeforms) may pass a.envvia--env-file, since the container runtime reads it; every other.envread stays blocked.
v0.10.0
Added
- UAT opens with a drive-mode ask (#178). Every acceptance-testing start (build/bug Verify, the Pending-UAT guard's run-now option, or any ticket carrying
UAT of:) now asks up front whether the UAT is AI-driven or human-driven. AI-driven runs the checks itself and hands the human only the steps it cannot perform; human-driven is the unchanged guided walkthrough. Skipped with a one-line reason when no step is agent-performable; an autonomous run takes it as delegate. A ticket whose body carriesUAT of: <parent>resolves through acceptance testing whatever its type label. - Run the UAT now, or open a UAT ticket? (#173). The Pending-UAT guard no longer opens a follow-up ticket on its own: when acceptance testing would otherwise be deferred at Resolve, it asks whether to run the UAT now (no ticket) or open a UAT ticket, and waits for an explicit answer.
quickalways size-triages (#175). Reaching forquickis itself the small-piece signal, so it now runs the size triage and the one consolidated ask-to-skip offer every time, independent ofconfig.effort(effortgoverns the map cycle only). Lean only on an explicit yes, no offer on a large ticket, and the correctness spine is never skipped.- Way-of-working step in the guided config (#171).
/trailhead:confignow reachesgit:,release:andisolation:through a new step that reads and writes thetrailhead:conventionsheader, so the isolation question is no longer skipped on a project that already has a config. - Assigned-ticket pre-check for
isolation: auto(#163). Before the work-start concurrency ask, other open tickets already assigned to you pre-bias the answer towardworktree/clone; the ask is skipped when the session is already inside the ticket's own worktree.
Changed / Fixed
- Pending follow-up guard (#176). A follow-up surfaced while working a ticket is carried into the final recap and re-posed before the
/clearblock as an explicit choice (open a tracked ticket, or let it go / do it later asquick), instead of being dropped or offered only asquick. workandquickdescribed correctly (#174, #179). The next-step block and the capture confirmation no longer frameworkas the split path or offerquicktwice;quick <n>on an existing ticket is described as the same ticket worked whole via the lighter no-split path (a map ticket stays on its map), and "off the map" is kept only forquick "<text>"and whiteboard tickets.- Host command forms (#170). A standing rule in the shared load contract keeps runtime prose (handoff, capture confirmations) on the running host's own command forms, so a Claude Code session no longer emits Codex-style commands.
- Question menus deduplicate (#177). Two questions that resolve the same decision are merged before a menu is shown; genuinely distinct questions stay separate.
- Grilling illustrates its options (#172). Each option offered in a grilling round now comes with a concrete illustration, so the user does not have to ask what it means.
- Grill close asks map vs whiteboard (#164). A standalone grill that surfaces build tickets now asks where they go instead of routing them to the whiteboard.
- Mockup fidelity is enforceable (#165). An approved mockup must be reproduced with 100% fidelity: Execute records an enumerated fidelity checklist as a ticket comment, and Verify checks against it (goal-backward statically, acceptance testing visually).
- Codex choices are selectable (#161, #162). The plain-text numbered list is now Codex's guaranteed choice path (
request_user_inputonly works in Plan Mode), and the guided-setup scope step is a selectable choice rather than free text. - Codex hook audit (#169). The
search-guardhook is no longer projected onto Codex, where it had no permission mechanism to protect and only blocked harmless commands; it stays Claude-only.
v0.9.0
Added
isolation: autois the new default (#156). Theisolation:convention header now defaults toauto: at a ticket's work-start the engine asks once whether more than one ticket will be worked at once on this machine this session, and if so resolves the mode by repo shape (a plain repo toworktree, a submodule superrepo toclone), otherwise it works in the current checkout exactly likenone. The autonomous run never asks (sequential work, no concurrency). An explicitnone/worktree/cloneis honoured as-is. A submodule-bearing repo escalatesworktreetoclone(a superproject worktree cannot safely carry submodule state), and a clone with submodules is provisioned recursively at the superproject's recorded commits. Documented in both READMEs,/docs, and the teamwork / configuration references./trailhead:pruneverb (verb badge now 22). A new verb that prunes a map's closed and orphan native sub-issue edges to reclaim slots under GitHub's 100-per-map cap (references are kept; only the structural edge is dropped). The child-to-map edge add is now cap-aware: at the cap the engine surfaces it and offers/trailhead:prunerather than silently dropping the edge, and the dashboard flags a map that isnear caporat cap · prunable. The prune gh mechanics are single-sourced and 404-tolerant (an already-detached edge is not an error). Projected on Codex as a discoverability skill.body-guardhook (guardrail #7) (#152). A new guardrail that hard-blocks agh issue edit/gh pr edit/gh apiwrite that would overwrite an issue or PR body with an empty or whitespace-only value, the backstop for the fail-safe body-rewrite rule. It recognises the-b/-F/--body/--body-fileforms,gh apiquoted and@fileempty-body shapes, and expands a leading~in body-file paths. The guardrail count is now seven across both READMEs and/docs. Registered on both Claude and Codex.- Brief the ticket and confirm scope before the work engine runs.
workandquicknow give a short, result-oriented summary of what resolving the ticket will do and ask whether to change anything before dispatching to the type engine. A change consistent with the ticket is folded in; a divergent request is surfaced as a mismatch and offered as work-as-is versus a separate new ticket (opened only if the user chooses it). Under an autonomous run this is a process confirm gate that proceeds without stopping. - Eager sub-issue edge drop at close (#151). When a ticket is closed as
trailhead:out-of-scopeortrailhead:superseded, its native sub-issue edge is now dropped at close to reclaim a slot immediately (references intact), instead of waiting for a later prune.
Changed / Fixed
- No agent-side action may be sequenced after
/clear(#159, #160). The handoff and capture specs now forbid sequencing after/clearan action the agent must perform that depends on context/clearwill erase; the fix is to do the agent action before the handoff, or convert the next step into a user-runnable command. The constraint now governs every line after/clear, not just commands (#159). The greenfield "pending codebase offer" was an attenuated instance: it is now posed and resolved before the/clear-first block is rendered rather than placed inside it (#160). - Next-step guidance anchors on
/trailhead:workover/trailhead:quick(#158, #149). The whiteboard / map-complete handoff branches, the bare-/trailheadempty-frontier move-list, the whiteboard render, and the capture and chart close blocks now anchor on/trailhead:work <n>and offer/trailhead:quick <n>only alongside as the no-split alternative, never in its place. - gh-subcommand hook detection hardened. The shared gh-subcommand library is now installed on every host, and flag detection handles two-token and unknown flags without desyncing the keyword scan (an unknown boolean gh flag can no longer hide a write).
- Injection scanner false positives reduced. The issue-injection scanner narrows its matched objects to cut prose false positives and tolerates padded imperative-override phrases.
- Miscellaneous. The post-commit self-check reads commit paths with
core.quotepath=falseso a non-ASCII filename compares plainly; the hookless update check rewrites its cache atomically;gh -Fcommand substitutions are quoted in the cookbook; and the ticket-language directive is asserted single-sourced by a test.
v0.8.1
Changed / Fixed
- Grilling and chart/adopt cover the full feature surface (#140). Grilling and the chart/adopt frontier steps deep-dived one thread and left whole functional areas uninterrogated, so large parts of the scope stayed silently as fog off the map. Grilling now runs a breadth-before-depth pass (enumerate every functional area first; an empty frontier reached while whole areas were never enumerated is a false finish, scoped to multi-part spaces so a single isolated choice still finishes on an empty frontier), and chart Mode 1 step 2 / adopt Mode 1-bis step 4 now require every functional area the destination implies to land on the map (fog under
## Not yet specifiedat minimum, or a ticket) before deep-diving, with the map (not the grilling transcript) as the coverage deliverable. - "Load first, in order" is single-sourced (#139). The identical
## Load first, in orderblock, previously duplicated across the dispatcher and the five clusterSKILL.mdfiles, is now single-sourced in_shared/load-first.md; each engine references it in one line and keeps only its own isolation tail. Guarded by a projection + source-level anti-drift test.
Both are internal engine / skill-doc quality changes (no runtime code changes).