Help us improve
Share bugs, ideas, or general feedback.
From hatch3r
Provides shared configuration, label taxonomy, branch conventions, and prerequisite checks for board commands (fill, groom, pickup, refresh). Loaded automatically by board-related skills.
npx claudepluginhub hatch3r/hatch3r --plugin hatch3rHow this skill is triggered — by the user, by Claude, or both
Slash command
/hatch3r:hatch3r-board-sharedThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Shared context for `hatch3r-board-fill`, `hatch3r-board-groom`, `hatch3r-board-pickup`, `hatch3r-board-refresh`, and related board commands. Read once per run and cache.
Regenerates board overview dashboard by scanning open issues, computing health metrics, and updating the meta:board-overview issue. Use for on-demand board health refresh.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
Shared context for hatch3r-board-fill, hatch3r-board-groom, hatch3r-board-pickup, hatch3r-board-refresh, and related board commands. Read once per run and cache.
Before reading configuration, validate that prerequisites are met. If any check fails, stop immediately with an actionable error message. For interactive sessions where credentials are missing, use the agents/shared/user-question-protocol.md plain-text fallback shape to offer the user a numbered choice (interactive login / paste-token / abort) instead of a bare stop message.
hatch.json exists: If .hatch3r/hatch.json is missing or unreadable, stop with:
"Board commands require a hatch3r project. Run
npx hatch3r initto set up your project first."
owner/repo configured: If both top-level owner/repo and board.owner/board.repo are empty, stop with:
"Board commands require owner and repo. Run
npx hatch3r configto set your repository identity, or provide them in.hatch3r/hatch.jsonunder the top-levelownerandrepofields."
Platform authentication: Verify CLI authentication for the configured platform. On failure, ASK via user-question-protocol with three numbered options (interactive login / paste-token / abort) and default to option 1 if no response.
gh auth status. If it fails or the project scope is missing, check GITHUB_TOKEN/GH_TOKEN env vars first; if absent, ASK: (1) gh auth login interactively, (2) paste a PAT with project scope (set GITHUB_TOKEN for this session only), (3) abort. Reference: https://docs.github.com/en/issues/planning-and-tracking-with-projectsaz account show. If it fails, check AZURE_DEVOPS_PAT; if absent, ASK: (1) az login interactively, (2) provide AZURE_DEVOPS_PAT, (3) abort. Confirm access to organization {namespace}.glab auth status. If it fails, check GITLAB_TOKEN; if absent, ASK: (1) glab auth login interactively, (2) provide GITLAB_TOKEN, (3) abort. Confirm access to project {namespace}/{project}.projectNumber set (for commands other than board-init): For board-fill, board-groom, board-pickup, and board-refresh, if board.projectNumber is null, stop with:
"No project board configured. Run the
board-initcommand first to create or connect a project board. This sets up the board.projectNumber in.hatch3r/hatch.json."
GitHub PAT project scope (GitHub only, for board-init/fill/groom/pickup): If GitHub mutations fail with permission errors, surface:
"GitHub Projects V2 requires the
projectscope on your PAT. Rungh auth refresh -s projectto add it. Classic PATs needadmin:orgfor org-owned projects."
Report each failed prerequisite with the specific fix command. Do not proceed past the first failure. Record each check's outcome (passed / failed-then-resolved / aborted) in the run cache errors entry for the end-of-run summary.
All board commands read project-specific configuration from .hatch3r/hatch.json. The GitHub owner and repo are defined at the top level (owner, repo). Board-specific configuration (Projects v2 IDs, label taxonomy, branch conventions, area labels) lives under the board key. Read .hatch3r/hatch.json at the start of every run and cache both top-level and board config for the duration.
Owner/repo resolution: Use top-level owner/repo. Fall back to board.owner/board.repo if top-level values are empty (backward compatibility).
{
"owner": "{github-org-or-user}",
"repo": "{repository-name}",
"board": {
"owner": "{github-org-or-user}",
"repo": "{repository-name}",
"defaultBranch": "main",
"projectNumber": null,
"statusFieldId": null,
"statusOptions": {
"backlog": null,
"ready": null,
"inProgress": null,
"inReview": null,
"done": null
},
"labels": {
"types": ["type:bug", "type:feature", "type:refactor", "type:qa", "type:docs", "type:infra"],
"executors": ["executor:agent", "executor:human", "executor:hybrid"],
"statuses": ["status:triage", "status:ready", "status:in-progress", "status:in-review", "status:done", "status:blocked"],
"meta": ["meta:board-overview"]
},
"branchConvention": "{type}/{short-description}",
"areas": []
},
"models": {
"default": "opus",
"agents": {
"hatch3r-lint-fixer": "sonnet"
}
}
}
board.defaultBranch — Branch used for checkout before creating feature branches, PR base branch, and release operations. Default: "main". Set to "master" or another branch name for repositories that use a different default.
If any field is null or missing, the corresponding feature is disabled (e.g., null projectNumber → skip Projects v2 sync).
models — Optional. Preferred AI models for agents. models.default applies to all agents; models.agents overrides per agent. Use aliases (opus, sonnet, codex, gemini-pro) or full model IDs. Resolution order: .hatch3r/agents/{id}.customize.yaml > manifest per-agent > agent frontmatter > manifest default. See Model Selection and Adapter Capability Matrix.
Read platform from .hatch3r/hatch.json. This determines all CLI commands, API patterns, and terminology for this run. If platform is missing or empty, default to github.
Platform-specific details: see
commands/board/shared-github.mdPlatform-specific details: seecommands/board/shared-azure-devops.mdPlatform-specific details: seecommands/board/shared-gitlab.md
Each platform sub-file contains: CLI command reference, MCP tool reference, terminology mapping, platform context, board sync procedure, sub-issue linking, board sync enforcement details, and CLI-first tooling directives.
Skip entirely if
board.projectNumberis null (GitHub/GitLab) or project is not configured (Azure DevOps).
Use this procedure whenever a status label is set or changes and the board needs to reflect it. Labels are the source of truth; board sync keeps the board view consistent. This includes newly created issues -- sync their initial status immediately after adding them to the board.
Platform-specific details: see
commands/board/shared-github.md(GitHub Projects V2 Sync) Platform-specific details: seecommands/board/shared-azure-devops.md(Azure Boards Work Item State Sync) Platform-specific details: seecommands/board/shared-gitlab.md(GitLab Board Label-Based Sync)
Use this procedure whenever a child issue must be linked to a parent epic. Board commands that create sub-issues MUST follow the platform-specific fallback chain and record the link status.
Platform-specific details: see
commands/board/shared-github.md(Sub-Issue Linking — GitHub) Platform-specific details: seecommands/board/shared-azure-devops.md(Sub-Issue Linking — Azure DevOps) Platform-specific details: seecommands/board/shared-gitlab.md(Sub-Issue Linking — GitLab)
Cache link status per child (native / advisory / comment-only) in the run cache under link_results.
Board sync is MANDATORY, not optional. The following rules override any "skip if null" or "skip silently" language elsewhere when the board is configured (GitHub: board.projectNumber set; Azure DevOps: project configured; GitLab: board configured).
has-dependencies label consistency: Every issue with a non-empty ## Dependencies section (containing at least one Blocked by or Recommended after reference) MUST have the has-dependencies label. Issues whose ## Dependencies section contains only None MUST NOT have the label. Board commands enforce this during creation and update.sync_results in the run cache.board.statusOptions.* key required by a planned sync mutation is null in .hatch3r/hatch.json, halt the mutation before it fires with: "Cannot sync {status:label}: board.statusOptions.{key} is null in .hatch3r/hatch.json. Run hatch3r-board-init to populate status option IDs." Do not proceed with remaining items in the batch.errors entry in addition to the per-item sync_results.All board commands that create or reorganize issues MUST follow this grouping policy. Epic grouping maximizes parallelization during pickup — agents can tackle multiple sub-issues of an epic concurrently, whereas standalone issues require serial pickup.
Target: zero standalone issues. Hard limit: no more than 10% of non-sub-issue items on the board should be standalone.
Calculate: standalone_count / (epic_count + standalone_count). Sub-issues are excluded from both numerator and denominator.
When the threshold is exceeded, board commands must apply progressively looser grouping strategies (area match → domain match → type match → catch-all epic) until the ratio is at or below 10%.
Apply these rules in strict priority order. Each rule reduces the remaining ungrouped pool before the next rule fires:
regroup action for execution.When a PR/MR merges and Closes #N auto-closes the referenced issues, the board item lifecycle must reach its terminal state. The status:in-review label should be replaced with status:done, and the board status should be set to "Done" using board.statusOptions.done.
Platform-specific behavior and recommendations:
board-init does) may not have it enabled. Verify the workflow is active: Project settings > Workflows > "Item closed" > confirm Status maps to "Done". If disabled, enable it. Without this workflow, the board status will remain "In Review" until board-groom detects and fixes the drift. GitHub does NOT auto-update labels on close — the status:in-review label remains on the closed issue.Fixes #N / Resolves #N syntax in PR descriptions for state transitions. Recommend checking this option consistently, or configuring it as the user's default.status::in-review scoped label remains on the closed issue. GitLab does not have a built-in "set label on close" automation. The status::done label must be applied manually, via a CI pipeline trigger on issue close events, or will be caught and fixed during board-groom drift remediation. Note: scoped labels (status::done) require GitLab Premium or Ultimate tier.Board commands that detect closed issues with status:in-review (or any non-status:done status label) should treat this as drift and remediate per the platform-specific sync procedure.
When a PR/MR is closed without merging, the referenced issues remain open with status:in-review. This is drift that must be resolved:
status:in-progress — if the developer intends to continue work on a different branch or rework the changes.status:ready — if the work is abandoned and the issue should return to the backlog for future pickup.board-groom Step 3l detects orphaned status:in-review issues (those with no open PR/MR referencing them). The user decides the target state during grooming.board-pickup Step 3, if collision detection finds a closed-without-merge PR for the selected issue, surface this context to the user so they can decide whether to reuse the branch, start fresh, or pick a different issue.This situation is NOT automatically remediated because the correct target state depends on developer intent. Board commands surface it as a diagnostic for user decision.
Every mutating board command (board-fill, board-groom, board-pickup) runs this procedure as its final step before the summary output. It catches silent failures and drift accumulated during the run.
sync_results shows a failure, using the full fallback chain with rule 8 retry semantics. If any item still fails after all retries, the command exits with non-zero status and emits the failing items as a list in the reconciliation report under Errors:. Do not suppress unresolved failures.link_results in the run cache. For links recorded as advisory, retry the platform-specific primary link method once to upgrade to native. Report all non-native links (advisory / comment-only) in the reconciliation output.type:*, priority:*, executor:*) and correct has-dependencies state per rule 7 of Board Sync Enforcement. Fix any gaps.status:in-progress or status:in-review, verify any associated open PR body contains Closes #N for the addressed issues. Auto-fix if missing by updating the PR body.status:in-review (not just those transitioned during this run), verify an open PR/MR exists that references Closes #N:
gh pr list -R {owner}/{repo} --state open --json number,body — parse for Closes #{N}.az repos pr list --status active — check work item links.glab mr list -R {namespace}/{project} --state opened — parse descriptions for Closes #{N}.
Flag orphaned in-review issues (those with no associated open PR/MR) in the reconciliation report. This catches issues that drifted to status:in-review in previous runs but lost their PR (closed without merge, PR deleted, etc.). Also flag closed issues still labeled status:in-review that should be status:done.Output the reconciliation report immediately before the command summary:
Reconciliation:
Board sync: {N} synced, {M} failed (list failures)
Sub-issue links: {N} native, {M} advisory, {K} comment-only
Label gaps: {N} fixed, {M} remaining (list)
PR linkage: {N} verified, {M} missing `Closes` (list)
Orphaned in-review: {N} open issues with no PR/MR, {M} closed issues not status:done (list)
Errors: {list or "None"}
Full details: see
commands/board/shared-board-overview.md(model pool, model selection heuristic, dashboard template, dependency data model, lane computation algorithm)
If meta:board-overview is included in board.labels.meta, board commands will look for an open issue with that label to use as a live dashboard. This dashboard is auto-maintained and MUST be regenerated at the end of every board command run that mutates issues. For on-demand regeneration without running a full board command, use hatch3r-board-refresh.
These directives apply to ALL board commands. They supplement the project's tooling hierarchy.
All board commands MUST use the platform CLI as the primary interface for operations. CLI tools have lower token cost and faster execution than MCP equivalents.
Platform-specific details: see
commands/board/shared-github.md(Cross-Cutting Tooling — GitHub CLI-First) Platform-specific details: seecommands/board/shared-azure-devops.md(Cross-Cutting Tooling — Azure DevOps CLI-First) Platform-specific details: seecommands/board/shared-gitlab.md(Cross-Cutting Tooling — GitLab CLI-First)
All board commands MUST minimize user approval prompts by batching related operations:
During board-fill Step 4c (external research) and board-pickup Step 6 (implementation):
resolve-library-id then query-docs) whenever an issue references an external library, framework, or SDK. This retrieves current, version-specific documentation to inform issue scoping and implementation.Board commands instruct the agent to invoke individual CLI / MCP calls; the agent harness already batches them. If the agent synthesises a wrapper shell script anyway, the script MUST be portable across the user's installed shells. macOS ships bash 3.2 as /bin/bash and many users default to zsh — bash-4-only features fail loudly on both.
gh issue create, gh issue edit, gh project item-add, az boards work-item create, or glab issue create loops in a synthesised bash script unless the user explicitly asks for a script artifact. The harness's parallel tool dispatch is cheaper than spawning a sub-shell and avoids the portability problem entirely.bash 3.2 (macOS system default). Banned constructs: declare -A (associative arrays), ${!ARR[@]} (associative-array key expansion), mapfile, readarray. Use parallel indexed arrays (KEYS=(), VALUES=()) with integer indices, or rewrite the batching logic in Python / Node. zsh is not a drop-in substitute — ${!ARR[@]} semantics differ; bad substitution is the symptom.#!/usr/bin/env bash and guard any bash-4+ feature behind [[ ${BASH_VERSINFO[0]} -ge 4 ]] || { echo "bash 4+ required, found ${BASH_VERSION}"; exit 64; } so the failure mode is loud, not silent.Every gh api, gh pr view, gh issue view, gh project item-list, az pipelines run, and glab api invocation from an agent-driven terminal MUST run with GH_PAGER=cat and PAGER=cat set. The default GitHub CLI pager (less) opens the alternate screen buffer, which returns empty captured output in non-TTY contexts — the call appears to succeed but its --jq output is lost. Piping to | cat does not bypass the alternate-buffer behaviour; the environment variables are the only reliable workaround.
Set once at the start of every board / PR command run, before the first CLI invocation:
export GH_PAGER=cat
export PAGER=cat
The export is idempotent and safe to re-set. GH_PAGER is scoped to gh; PAGER covers downstream git, az, or glab invocations. This directive applies to every command in this directory tree.
- [ ] #{number} {short title} *({type tag, }{priority})*Epic for epics, omitted for standalone.[Type]: prefix.P0-P3 or --.Single source of truth for the todo.md line format shared by the producers (hatch3r-roadmap Step 5, hatch3r-project-spec Step 6) and the consumer (hatch3r-board-fill Step 1). Producers MUST emit this grammar; board-fill MUST parse it with the rules below so checkbox glyphs and scope tags never leak into issue titles and priority headers never parse as items.
Line forms:
| Form | Pattern | Parse as |
|---|---|---|
| Priority header | ## P{N} — {Label} (N = 0–3) | Section header — sets the priority:p{N} default for items beneath it. NOT a todo item. |
| Future-ideas header | ## Future Ideas | Section header — items beneath it default to priority:p3. NOT a todo item. |
| Todo item | - [ ] **[{TAG}] {Title}**: {Description}[ Ref: {path}.] | One todo item. {TAG} ∈ {BIZ, TECH, BOTH}. |
Parse rules (board-fill Step 1 applies in order):
^## (priority header or ## Future Ideas) is a section marker, not an item. Record its P{N} value (or p3 for ## Future Ideas) as the priority default for items until the next header.- or * ) and, if present, a checkbox token ([ ] or [x], case-insensitive) that immediately follows it. Lines without - /* are not items.**[{TAG}] token; capture {TAG} ∈ {BIZ, TECH, BOTH} and remove it from the title. BIZ → business-driven, TECH → technically-driven, BOTH → cross-cutting. Feed the tag into Step 3 classification (area/executor lean), not the title.**…** is the item title (strip the surrounding **); the text after the first : is the description. A trailing Ref: {path}. carries the source spec/ADR path — surface it as a documentation reference, not part of the title.P{N} as the item's default priority:* (overridable by Step 3 triage). Items above the first header default to p2.Items not matching the todo-item form (blank lines, prose, stray bullets without a **[{TAG}]…** span) are skipped with a one-line note in the parsed-list output so the user can correct malformed entries.
Reference library — no fan-out. This skill ships shared board context (configuration, sync procedures, tooling directives) consumed by the delegating board commands (board-fill, board-pickup, board-init, board-refresh, board-groom). It spawns no sub-agents itself; fan-out is owned by the consuming command per its own Fan-out Discipline block. Source: rules/hatch3r-fan-out-discipline.md (P8 B2).
These apply to all board commands. Follow them to minimize token consumption.
meta:board-overview issue exists, board commands MUST regenerate it ONCE at the end of the run. Do not regenerate after intermediate status changes, and do not skip the final regeneration.All mutating board commands MUST maintain a run cache with the following entries. The cache persists for the duration of the run and feeds into the End-of-Run Reconciliation Procedure.
| Key | Type | Description |
|---|---|---|
created_issues | Map<number, {title, type, labels}> | All issues created during this run |
updated_issues | Map<number, {title, changes[]}> | All issues updated during this run |
sync_results | Map<number, {status: success|failure, method: cli|mcp|skipped}> | Board sync outcome per issue |
link_results | Map<number, {parent: number, status: native|advisory|comment-only}> | Sub-issue link outcome per child |
pr_created | {number, branch, issues_closed[]} or null | PR created during this run (if any) |
pr_association_map | Map<number, number[]> | PR number → issue numbers it references |
board_item_ids | Map<number, string> | Issue number → board item ID for subsequent updates |
errors | {step, issue?, message, recoverable}[] | All errors encountered during the run |
Initialize all entries at the start of the run. Populate incrementally as operations execute. The reconciliation procedure reads these entries to detect and fix drift.
project scope requirement (gh auth refresh -s project), the classic-PAT admin:org note, and the GITHUB_TOKEN/GH_TOKEN fallback in the prerequisites/authentication section.