x-internal-precheck-worktree
Classifies the git working tree state (CLEAN/DIRTY/DIVERGENT/AMBIGUOUS) and returns a stable exit code. Invoked by orchestrators before starting story/task execution to detect dirty or divergent states early. Exit 0 = CLEAN or DIRTY; exit 15 (WORKTREE_AMBIGUOUS) = DIVERGENT or AMBIGUOUS (unless --allow-dirty).
- License 许可
- MIT
- 最近更新
- 2026-10-27
- Stars
- ★ 0
- Forks
- 1
01 前言 Front Matter
- name
- x-internal-precheck-worktree
- model
- haiku
- visibility
- internal
- description
- Classifies the git working tree state (CLEAN/DIRTY/DIVERGENT/AMBIGUOUS) and returns a stable exit code. Invoked by orchestrators before starting story/task execution to detect dirty or divergent states early. Exit 0 = CLEAN or DIRTY; exit 15 (WORKTREE_AMBIGUOUS) = DIVERGENT or AMBIGUOUS (unless --allow-dirty).
- allowed-tools
- [ "Bash" ]
- argument-hint
- [--allow-dirty] [--repo-path <path>]
- context-budget
- light
- user-invocable
- false
- requires-capabilities
- []
03 SKILL.md 正文
🔒 INTERNAL SKILL — Invoked only by other skills via the Skill tool. Not user-invocable.
Purpose
Runs git status --porcelain and git rev-list --count --left-right @{upstream}...HEAD
to classify the working tree, returning one of 4 states:
| State | Dirty files? | Upstream divergence? | Exit code |
|---|---|---|---|
CLEAN |
No | No | 0 |
DIRTY |
Yes | No | 0 (warning emitted) |
DIVERGENT |
No | Yes | 15 (WORKTREE_AMBIGUOUS) |
AMBIGUOUS |
Yes | Yes | 15 (WORKTREE_AMBIGUOUS) |
Exit code 15 is the stable contract for orchestrators to dispatch on (RULE-010, EPIC-0061).
Usage
Skill(skill: "x-internal-precheck-worktree", args: "--repo-path <path>")
Skill(skill: "x-internal-precheck-worktree", args: "--allow-dirty --repo-path <path>")
Parameters
| Flag | Default | Description |
|---|---|---|
--allow-dirty |
false |
When set, DIRTY/AMBIGUOUS/DIVERGENT return exit 0 with a WARNING rather than exit 15. Used in recovery contexts. |
--repo-path |
. (cwd) |
Path to the git repository root. Default: current working directory. |
Output
Emits to stdout a single-line JSON envelope:
{ "state": "CLEAN|DIRTY|DIVERGENT|AMBIGUOUS", "dirtyCount": 0, "ahead": 0, "behind": 0 }
Stderr carries a human-readable summary for operator visibility.
Exit Codes
| Exit | Code | Meaning |
|---|---|---|
| 0 | OK |
Working tree is CLEAN or DIRTY (non-blocking). Orchestrator may proceed. |
| 15 | WORKTREE_AMBIGUOUS |
Working tree is DIVERGENT or AMBIGUOUS. Orchestrator MUST block unless --allow-dirty. |
| 2 | OPERATIONAL_ERROR |
git not found on PATH or --repo-path is not a git repository. |
Telemetry
<!-- TELEMETRY: phase.start -->
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh subagent-start x-internal-precheck-worktree worktree-precheck
<!-- TELEMETRY: phase.end -->
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh subagent-end x-internal-precheck-worktree worktree-precheck ok
Implementation
#!/usr/bin/env bash
set -euo pipefail
ALLOW_DIRTY=false
REPO_PATH="."
while [[ $# -gt 0 ]]; do
case "$1" in
--allow-dirty) ALLOW_DIRTY=true; shift ;;
--repo-path) REPO_PATH="$2"; shift 2 ;;
*) echo "OPERATIONAL_ERROR: unknown arg $1" >&2; exit 2 ;;
esac
done
command -v git >/dev/null 2>&1 || { echo "OPERATIONAL_ERROR: git not found on PATH" >&2; exit 2; }
[[ -d "$REPO_PATH/.git" ]] || git -C "$REPO_PATH" rev-parse --git-dir >/dev/null 2>&1 || \
{ echo "OPERATIONAL_ERROR: $REPO_PATH is not a git repository" >&2; exit 2; }
STATUS=$(git -C "$REPO_PATH" status --porcelain 2>/dev/null || true)
UPSTREAM=$(git -C "$REPO_PATH" rev-list --count --left-right "@{upstream}...HEAD" 2>/dev/null || true)
DIRTY_COUNT=$(echo "$STATUS" | grep -c '.' || true)
BEHIND=$(echo "$UPSTREAM" | awk '{print $1}' || echo "0")
AHEAD=$(echo "$UPSTREAM" | awk '{print $2}' || echo "0")
[[ -z "$STATUS" ]] && DIRTY_COUNT=0
IS_DIRTY=$([[ "$DIRTY_COUNT" -gt 0 ]] && echo true || echo false)
IS_DIVERGENT=$([[ -n "$UPSTREAM" ]] && echo true || echo false)
if $IS_DIRTY && $IS_DIVERGENT; then STATE="AMBIGUOUS"
elif $IS_DIVERGENT; then STATE="DIVERGENT"
elif $IS_DIRTY; then STATE="DIRTY"
else STATE="CLEAN"
fi
echo "{ \"state\": \"$STATE\", \"dirtyCount\": $DIRTY_COUNT, \"ahead\": $AHEAD, \"behind\": $BEHIND }"
if [[ "$STATE" == "DIRTY" ]]; then
echo "WARN [worktree-precheck] working tree has $DIRTY_COUNT uncommitted file(s) — proceeding (not divergent)" >&2
fi
if [[ "$STATE" == "DIVERGENT" || "$STATE" == "AMBIGUOUS" ]]; then
if $ALLOW_DIRTY; then
echo "WARN [worktree-precheck] $STATE state — allowed by --allow-dirty" >&2
exit 0
fi
echo "WORKTREE_AMBIGUOUS: $STATE — use --allow-dirty to bypass or resolve with git stash/pull" >&2
exit 15
fi
exit 0
Integration Notes
- Invoked by:
x-implement-story(Phase 0.3 worktree-first branch decision),x-implement-task(Step 0),x-implement-epic(Phase 2 pre-guard). - Dispatching on exit 15 (
WORKTREE_AMBIGUOUS) is the canonical non-interactive response; orchestrators MUST NOT callAskUserQuestionin response — they emitWORKTREE_AMBIGUOUSto the operator and halt. - Java implementation:
dev.iadev.cli.skill.WorktreePrecheck(EPIC-0061, TASK-0061-0001-001) provides the same classification logic for generator-internal use.
04 同仓库更多 Skills
x-parallel-eval
Detects and classifies file-collision risks between work units (tasks, stories, or epic phases) before parallel execution. Reads ## File Footprint blocks produced by x-task-plan / x-story-plan, applies the parallelism-heuristics knowledge pack (hard / regen / soft categories + hotspot overrides), and emits a collision matrix + serialization recommendation in Markdown (default) or JSON.
parallelism-heuristics
Canonical catalog of file-collision heuristics for parallel task, story, and epic execution. Defines the File Footprint block format, the three Conflict Categories (hard / regen / soft), a hotspot list of high-contention paths, and the degrade-with-warning policy. Consumed by x-task-plan, x-story-plan, x-epic-map, x-parallel-eval, and x-dev-*-implement.
x-watch-pr-ci
Polls a PR's CI checks and Copilot review status, blocking until checks complete or timeout. Returns one of 8 stable exit codes (SUCCESS=0, CI_PENDING_PROCEED=10, CI_FAILED=20, TIMEOUT=30, PR_ALREADY_MERGED=40, NO_CI_CONFIGURED=50, PR_CLOSED=60, PR_NOT_FOUND=70). Writes a versioned state-file for session resume.
x-validate-docs
Documentation freshness gate: validates 6 dimensions (readme, api-specs, grpc-proto, adr, skill-docs, system-architecture) against code changes in a PR. Stack-aware — only validates targets declared/auto-detected from ProjectConfig.documentation.targets. Returns exit non-zero on staleness; produces structured report.
x-update-system-architecture
Incrementally updates docs/architecture/system.md after an epic completes. Appends new entries to the Decision Log (§11) using x-internal-write-report --append (dedup by ## ID: marker) and surgically inserts component/integration changes into sections 1-10 via Edit. Idempotent: re-running with the same epic produces a byte-identical system.md.
x-update-architecture
Incrementally updates the service architecture document with changes from architecture plans. Adds new components, integrations, flows, and ADR references without rewriting existing content. Use after implementation to keep architecture documentation current.