From b7c14a143804a40bab3b5d3da6879bf021086d67 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 07:39:12 +0000 Subject: [PATCH] fix(source-control): emit worktree_lock state when arming liveness guard Lock failures still warn and exit 0, but stderr now carries worktree_lock=armed|unarmed for orchestrators. Fixes #2389 Co-authored-by: Kyle Sexton --- .../source-control/.claude-plugin/plugin.json | 2 +- plugins/source-control/CHANGELOG.md | 16 ++++++++++++++++ .../source-control/scripts/worktree-create.sh | 3 +++ .../scripts/worktree-create.test.sh | 3 ++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/plugins/source-control/.claude-plugin/plugin.json b/plugins/source-control/.claude-plugin/plugin.json index ed79d601c..71afbf791 100644 --- a/plugins/source-control/.claude-plugin/plugin.json +++ b/plugins/source-control/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "source-control", - "version": "0.53.2", + "version": "0.53.4", "description": "Git and GitHub delivery workflow: /commit (Conventional Commits + Co-Authored-By trailer via safe heredoc mechanics), /pull-request (prep, create, CI monitoring, review-comment triage, merge, CI-log fetch), /babysit-prs (self-pacing fleet loop \u2014 safe by default; opt-in worker/autopilot tiers add gate-checked merge and thread resolution behind a deterministic Python engine), /babysit-loop (the loop-lane merge lane: a standing or drain loop that invokes babysit-prs per cycle, configured through repo-scoped babysit_loop_* keys on the layered source-control.md seam, with merge authority human-only until the target repo's tracked config adopts the lane, a gate-proven C2-mechanical baseline once adopted, and standing merge-rung raises binding from the team-tracked layer only \u2014 with one named exception, where an invocation line explicitly typing both the autopilot tier keyword and the dedicated raise argument --merge c3-this-run widens that single invocation's merge authority up to C3 behind a fresh independent frontier-tier resolver, while C4-structural and C5-untrusted-provenance stay unconditionally human-merge), /worktree (create, status, cleanup, audit for parallel-session isolation), /setup (check the effective commit-subject / PR-title convention merged across its config layers and the babysit-prs config, or apply \u2014 interview the repo and write the convention config to a chosen layer), and /resolve-conflicts (intent-first merge/rebase conflict resolution with a semantic-conflict sweep \u2014 never --abort). The commit-subject / PR-title convention is configurable via a source-control.md config written by a re-runnable setup skill, layered across a ~/.claude user-global file, the tracked team file, and a gitignored .claude/source-control.local.md personal overlay merged per key; Conventional Commits is the default when no convention is declared.", "author": { "name": "Melodic Software", diff --git a/plugins/source-control/CHANGELOG.md b/plugins/source-control/CHANGELOG.md index 92548d5b6..bd61d2afb 100644 --- a/plugins/source-control/CHANGELOG.md +++ b/plugins/source-control/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to the `source-control` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.53.3] + +### Fixed + +- **`fetch_pull_request_commits` fails closed when the pull-commits walk is shorter than the PR's + `commits` count (#2387).** GitHub caps that endpoint at 250 commits regardless of pagination; the + helper now compares against the PR metadata and raises instead of returning a silently truncated + list. + +## [0.53.4] + +### Fixed + +- **`worktree-create.sh` emits `worktree_lock=armed|unarmed` on stderr (#2389).** Lock failures + still warn and exit 0, but orchestrators can see when the liveness guard did not arm. + ## [0.53.2] ### Fixed diff --git a/plugins/source-control/scripts/worktree-create.sh b/plugins/source-control/scripts/worktree-create.sh index 72ac8b33d..8d3b6839a 100755 --- a/plugins/source-control/scripts/worktree-create.sh +++ b/plugins/source-control/scripts/worktree-create.sh @@ -665,7 +665,9 @@ fi # absent (#2257). The owning lane (or cleanup, after explicit confirmation) # disarms with `git worktree unlock `. lock_reason="worktree-create.sh: lane active on ${HOSTNAME:-$(hostname 2>/dev/null || printf 'unknown-host')} since $(date -u +%Y-%m-%dT%H:%M:%SZ); unlock when the owning lane is done" +worktree_lock_state=armed if ! git -C "$toplevel" worktree lock --reason "$lock_reason" "$worktree_path" >&2; then + worktree_lock_state=unarmed printf '%s: warning: could not lock the new worktree — cleanup sweeps will not see it as claimed\n' "$PROG" >&2 fi @@ -702,4 +704,5 @@ if [[ -f "$include_file" ]]; then fi printf '%s: created worktree on branch %q (base %s)\n' "$PROG" "$name" "$base_ref" >&2 +printf '%s: worktree_lock=%s\n' "$PROG" "$worktree_lock_state" >&2 printf '%s\n' "$worktree_path" diff --git a/plugins/source-control/scripts/worktree-create.test.sh b/plugins/source-control/scripts/worktree-create.test.sh index 684db53af..a29d9e2c9 100755 --- a/plugins/source-control/scripts/worktree-create.test.sh +++ b/plugins/source-control/scripts/worktree-create.test.sh @@ -770,8 +770,9 @@ assert_file_absent "--root-file NUL-collapsed path never materialized" \ repo=$(mkrepo --origin "git@github.com:acme/widget.git") root_file="$TEST_TMPDIR/rootfile-lock" printf '%s' "$TEST_TMPDIR/wtroot18-lock" > "$root_file" -out=$(bash "$HELPER" --name feat/liveness --root-file "$root_file" --repo-dir "$repo" 2>/dev/null) +out=$(bash "$HELPER" --name feat/liveness --root-file "$root_file" --repo-dir "$repo" 2>"$TEST_TMPDIR/wt-lock-stderr") assert_exit "lock case: creation succeeds (exit 0)" 0 "$?" +assert_contains "lock state is machine-readable on stderr" "$(cat "$TEST_TMPDIR/wt-lock-stderr")" "worktree_lock=armed" stanza=$(git -C "$repo" worktree list --porcelain | awk -v RS= -v p="acme-widget-feat-liveness" 'index($0, p)') assert_contains "the new worktree is locked at creation" "$stanza" "locked" assert_contains "the lock reason names the arming helper" "$stanza" "worktree-create.sh"