fix(build): idempotent resume for worktree/branch/PR (state-resume contract) #9

Merged
kaykayyali merged 1 commits from fix/build-idempotency-recovery into main 2026-06-24 04:14:49 +00:00
Owner

What

  • ensure_worktree branch-exists fallback (src/damascus/git_ops.py): when feat/<story_id> already exists on the remote, fall back to git worktree add <path> <branch> (no -b) instead of failing on git worktree add -b <existing-branch>.
  • open_pull_request GET-then-POST (src/damascus/git_ops.py): check GET /pulls?head=<branch>&state=all before POSTing; return existing PR URL if found, else POST as before.
  • 2 new contract tests (tests/contract/test_contracts_match_source.py): guard the no--b shape and the GET-then-POST shape against regressions.

Why

State-resume-protocol.md "Idempotency contract" requires three pre-write checks in build():

  • worktree (already worked: worktree_path.exists() short-circuit)
  • branch (NEW: was failing on git worktree add -b <existing> after partial state)
  • PR (NEW: was failing on 422 from duplicate POST /pulls)

The 3-txn split in PR #8 makes these gaps more likely to surface — a row in build with claimed_at within the stale-claim window is now more recoverable, so build() will hit partial-state recovery more often.

Test

  • 17/17 contract tests pass locally (including the 2 new ones).
  • Manual smoke test confirmed: git worktree add -b <existing-branch> main fails; git worktree add <path> <existing-branch> succeeds.
## What - **`ensure_worktree` branch-exists fallback** (`src/damascus/git_ops.py`): when `feat/<story_id>` already exists on the remote, fall back to `git worktree add <path> <branch>` (no `-b`) instead of failing on `git worktree add -b <existing-branch>`. - **`open_pull_request` GET-then-POST** (`src/damascus/git_ops.py`): check `GET /pulls?head=<branch>&state=all` before POSTing; return existing PR URL if found, else POST as before. - **2 new contract tests** (`tests/contract/test_contracts_match_source.py`): guard the no-`-b` shape and the GET-then-POST shape against regressions. ## Why State-resume-protocol.md "Idempotency contract" requires three pre-write checks in `build()`: - ✅ worktree (already worked: `worktree_path.exists()` short-circuit) - ❌ branch (NEW: was failing on `git worktree add -b <existing>` after partial state) - ❌ PR (NEW: was failing on 422 from duplicate `POST /pulls`) The 3-txn split in PR #8 makes these gaps more likely to surface — a row in `build` with `claimed_at` within the stale-claim window is now more recoverable, so `build()` will hit partial-state recovery more often. ## Test - 17/17 contract tests pass locally (including the 2 new ones). - Manual smoke test confirmed: `git worktree add -b <existing-branch> main` fails; `git worktree add <path> <existing-branch>` succeeds.
kaykayyali added 1 commit 2026-06-24 04:14:21 +00:00
fix(build): idempotent resume for worktree/branch/PR (state-resume contract)
All checks were successful
test / contract-and-unit (pull_request) Successful in 17s
08912d0ec9
State-resume-protocol.md requires three pre-write checks in build():
1. Worktree — already worked (worktree_path.exists() short-circuit)
2. Branch — was failing on 'git worktree add -b <existing-branch>' after
   partial state; fall back to no-'-b' form to check out existing branch
3. PR — was failing on 422 from duplicate 'POST /pulls'; check existing
   PR first via 'GET /pulls?head=<branch>&state=all' and return its URL

The 3-txn split (PR #8) makes these gaps more likely to surface.

2 new contract tests guard the post-fix shape against regressions.
kaykayyali merged commit 510c25c71a into main 2026-06-24 04:14:49 +00:00
kaykayyali referenced this issue from a commit 2026-06-24 04:14:51 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kaykayyali/damascus-orchestrator#9