Working as a team
Many people (and their agent sessions) share one map and work it concurrently:
- Claim = assign to yourself. The claimer owns the ticket end to end and closes it: there is no approver and no one to wait on. On a claim collision the session stops and asks you, rather than resolving it silently.
- Split an oversized ticket into children and supersede the original (
/trailhead:split). - Pause/resume via a
PAUSEDcheckpoint comment, so any session can pick a ticket back up. - Isolate concurrent sessions with worktrees. Claiming keeps two sessions off the same ticket, but two sessions on different tickets in the same clone still share one working tree. Set
isolation: worktreein the conventions header and each executing ticket runs in its owngit worktreeon atrailhead/t<n>branch, integrated back to the trunk at Resolve. It implies a branch per ticket even undergit: main(git won’t check the trunk out twice), and it’s the right posture for a monorepo (a worktree shares the object store, far cheaper than a second clone). One caveat: a worktree isolates source but is a fresh path with no installed deps, so a path-bound package (React Native/Expo, native toolchains, anything tied to a localnode_modules) won’t build from it. For those there’sisolation: clone: a dedicated per-ticket clone that installs its own deps and builds/UATs like the real app (heavier than a worktree, and the right tool for an Expo/RN submodule). Or keepisolation: noneand serialize. Otherwise run concurrent sessions in separate clones. - A session-ticket marker for your statusline. When it starts working a ticket, trailhead drops a one-line, gitignored
.trailhead/session-ticket(#<n> <title>) at the working root and clears it at handoff. It’s purely a cheap, offline hint so a statusline (or any tool) can show which ticket this session is on without hitting the tracker; trailhead itself still treats the Issues as the source of truth. - It nudges you when isolation was never chosen. If a repo was charted or adopted before you set an
isolation:mode (so it silently defaults tonone), the first time you go to work a ticket with a real collision risk (another ticket in progress, or path-bound tooling in itsScope:) trailhead surfaces a one-line suggestion of the fitting mode (worktreeorclone) instead of quietly editing the shared checkout. Whatever you decide, including keepingnone, it writes theisolation:key into the conventions so the choice is recorded and it never asks again. A header that already setisolation:is left alone. - Scope tickets by path on a monorepo. A ticket can carry a
Scope:line naming the package/dir(s) it touches: disjoint scopes parallelize safely, and it scopes build/test and the worktree’s commits to the affected package./trailhead:adoptdetects a monorepo and proposes bothisolation: worktreeand theScope:convention. Underisolation: none,Scope:also serializes a shared area: at claim time a session holds off if another in-progress ticket’s scope overlaps, so two tickets scoped to the same submodule/package can’t run at once (how you keep two sessions off one path-bound app). - Git submodules are handled as separate repos. Work that lands inside a submodule is committed inside the submodule plus a gitlink bump in the parent, and (under
worktree) isolated at the submodule, not the superproject. A ticket spanning two submodules stays atomic via a single parent commit that bumps both gitlinks together; itsScope:names both./trailhead:adoptdetects.gitmodulesand writes the rule into the conventions. - State lives on the tickets (claim, labels, comments; all conflict-free); the map body is a re-readable index, not the source of truth. The durable record of a resolution is the ticket’s own comment.
- Labels are protected from outsiders.
trailhead:*labels drive the map, so trailhead trusts a labelled issue only when a write-access collaborator applied the label and (for a ticket) it carries a validParent:. Anything else is quarantined astrailhead:unverified, off the frontier. GitHub already blocks non-write users from labelling; against triage users and automations, trailhead can install the label guard GitHub Action for you into your repo’s.github/workflows/, where it strips unauthorizedtrailhead:*labels at the source. Installing a workflow needs a token with theworkflowscope, so trailhead runsgh auth refresh -s workflowif the push is rejected. - Issues opened by others are triaged, not trusted blindly.
/trailhead:inboxlists inbound issues (bug reports, requests, questions that aren’t yet trailhead tickets) and integrates the worthwhile ones in place: reframing them as tickets, keeping the reporter’s authorship, and applying the labels on adoption. The rest routes to fog, out-of-scope, duplicate, or needs-info.
Several maps at once: a repo can carry more than one live map (parallel milestones or features), each with its own scoped frontier, so two people can drive two efforts on the same repo without stepping on each other, and you can park one map to work another.
Next: Configuration for the isolation: and other conventions keys, or Commands for the verbs mentioned above.