Skip to content

fix(swarm): post-0.5.0 review fixes — merge winner, in-flight validate, timeouts, port ranges - #28

Merged
Steel-tech merged 2 commits into
mainfrom
worktree-swarm-review-fixes
Oct 15, 2026
Merged

Steel-tech merged 2 commits into
mainfrom
worktree-swarm-review-fixes

Conversation

@Steel-tech

@Steel-tech Steel-tech commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Fixes from the review of the 0.4 roadmap work (#21) that were still present in 0.5.0. This work was done on Oct 6 and stayed on this machine until now. There's no behavior change beyond what's listed here.

Safety

  • Merge winner re-checks finished slots before skipping them. Before this fix, it took "finished" from the compare table. A marker finish is never cleared, so an agent given a follow-up could be skipped and, on a clean worktree, archived (which kills it). It now runs settle after the merge and re-reads compare. A slot is skipped only if it is still finished, with the tip and dirty count the operator saw. Base drift is checked against the base at confirm time. Before, the check re-read the base first and so compared the new base to itself.
  • Archive, discard and abort refuse while a slot's validate hook is running. The hook runs with the repo lock released and could write files after the cleanup inventory or discard snapshot was taken.
  • with_timeout / with_group_timeout parse their duration before forking. 2m or 0900 used to error after the child had started, which killed the caller and left cp or the validate hook running with no deadline. Fan-out now refuses a bad clone or setup timeout before any worktree exists.

Correctness

  • Per-repo port ranges via git config swarm.portStart / swarm.portSpan. The env-only override never reaches a pane opened by a plugin action, so two repos collided on 4100.
  • validate exits 36, not 30, when the slot moved while the hook ran. 30 means the base moved.
  • Compare and the strict candidate gate share one validation-identity rule (isSwarmValidationRecord). Compare's copy had drifted and could rank passed a record the handoff rejects.
  • A validate timeout now names HERDR_SWARM_VALIDATE_TIMEOUT, not the generic step timeout.

Tests and docs

  • New tests: merge winner re-reads finished state; refusal while a hook is running; timeout parsing (including octal-looking values); port ranges set through git config; the git-routing list held identical between the renderer and lib.sh; direct git spawns in bin/ must be read-only; compare ranking ties.
  • CONCEPTS (Finished, Finish marker, Compared tip, Validation result, the two meanings of "settle"), README, CHANGELOG [Unreleased], and residual review findings addenda.

Verification

npm run validate on macOS: manifest and source checks, shellcheck -x scripts/*.sh clean, node --test 371 passed, 0 failed, 1 skipped (the Linux-only copy-on-write test, skipped on macOS by design). bash -n scripts/*.sh clean. CI covers ubuntu.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Configure swarm port ranges per repository, with environment settings taking precedence.
    • Automatically validate slots when they finish, and use an optional expected commit when merging.
  • Bug Fixes
    • Merge now stops if the base commit changes, and skips other slots only when their work remains unchanged and finished.
    • Archive, discard, and abort now leave slots untouched while validation is running.
    • Invalid timeout settings are rejected before work begins; decimal values are handled correctly.
    • Validation comparisons reject stale or mismatched results, and ranking excludes slots that are no longer running.
  • Documentation
    • Clarified finish, validation, and comparison behavior.

Steel-tech and others added 2 commits October 6, 2026 12:41
…validate, parse timeouts first

Fixes from the review of the 0.4 roadmap work (#21), all still present on
0.5.0:

- Merge winner took "finished" from the compare table. A marker finish is
  never cleared, so an agent given a follow-up was skipped and, on a clean
  worktree, archived (which kills it). It now runs settle after the merge
  and re-reads compare; a slot is skipped only if still finished with the
  tip and dirty count the operator saw. It also checks base drift against
  the base at confirm: re-reading it first made the check compare new to new.
- Archive, discard and abort refuse while a slot's validate hook runs. The
  hook runs with the repo lock released and could write files after the
  cleanup inventory or discard snapshot.
- with_timeout / with_group_timeout parse their duration before forking.
  "2m" or "0900" errored after the child started, killing the caller and
  orphaning cp or the validate hook with no deadline. Fan-out refuses a bad
  clone or setup timeout before any worktree exists.
- Per-repo port ranges via git config swarm.portStart/portSpan. The env-only
  override never reaches an action-invoked pane, so two repos collided on
  4100 with no way out. (The plugin config dir would not fix it: it is
  shared by every repo.)
- validate exits 36, not 30, when the slot moved during the hook; 30 means
  the base moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e candidate gate

Second pass on the post-0.5.0 review fixes.

- Compare kept its own copy of "is this Swarm's validation record for this
  run and slot". It had drifted from the strict candidate gate's copy: it
  did not require schema_version 1 or the hook's own `validate` check, so
  compare could rank `passed` a record the handoff then rejects. Both now
  call isSwarmValidationRecord from pr-handoff.mjs; a test pins compare to
  the import.
- A timed-out `validate` in the harvest pane named
  HERDR_SWARM_STEP_TIMEOUT_MS, but validate's budget follows
  HERDR_SWARM_VALIDATE_TIMEOUT. The banner now names the right knob.
- Tests: the renderer's GIT_ROUTING list is held in lockstep with
  lib.sh clear_git_routing_env; the bin/ read-only-git check now also
  covers direct spawn/exec of git; compare ranking ties are asserted
  (commits > finished > neither, never diff size).
- CONCEPTS gains Finished, Finish marker, Compared tip and Validation
  result, and notes the two meanings of "settle". README, CHANGELOG and the
  residual review findings are brought in line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d17eb26f-769f-4bc0-bd77-3551c7e2004b
📥 Commits

Reviewing files that changed from the base of the PR and between f750bc7 and 3ebeda2.

📒 Files selected for processing: 19
  • CHANGELOG.md
  • CONCEPTS.md
  • README.md
  • bin/renderer-harvest.mjs
  • docs/residual-review-findings/finish-detection-2026-10-03.md
  • docs/residual-review-findings/validate-verb-2026-10-03.md
  • scripts/abort.sh
  • scripts/compare.mjs
  • scripts/fanout-pane.sh
  • scripts/harvest-step-settle.sh
  • scripts/harvest-step-slot.sh
  • scripts/harvest-step-validate.sh
  • scripts/lib.sh
  • scripts/pr-handoff.mjs
  • scripts/preflight.sh
  • tests/compare.test.mjs
  • tests/fanout.test.mjs
  • tests/harvest.test.mjs
  • tests/validate.test.mjs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

This change updates port and timeout configuration, validation-record checks, protection for worktrees with active validation hooks, and compare-and-merge handling. It also updates documentation and tests for these behaviors.

Changes: Swarm workflows

Layer / File(s) Summary
Port settings and timeout preflight
CHANGELOG.md, README.md, scripts/preflight.sh, scripts/fanout-pane.sh, scripts/lib.sh, tests/fanout.test.mjs
Port settings can come from environment variables or repository Git config, with defaults. Fan-out and timeout helpers reject invalid timeout values before creating worktrees or starting commands.
Validation records and worktree protection
CONCEPTS.md, README.md, CHANGELOG.md, scripts/pr-handoff.mjs, scripts/compare.mjs, scripts/harvest-step-validate.sh, scripts/harvest-step-slot.sh, scripts/abort.sh, scripts/lib.sh, scripts/harvest-step-settle.sh, tests/compare.test.mjs, tests/validate.test.mjs, docs/residual-review-findings/*
Validation evidence uses a shared check for schema, run, slot, and hook identity. Slot changes during validation return refusal. Archive, discard, and abort keep a worktree while its validation process is active.
Compare and merge confirmation
bin/renderer-harvest.mjs, scripts/compare.mjs, README.md, CHANGELOG.md, CONCEPTS.md, docs/residual-review-findings/finish-detection-2026-10-03.md, tests/compare.test.mjs, tests/harvest.test.mjs
Winner confirmation records the base SHA and other candidates’ tips and dirty counts. Merge refuses a changed base and rechecks finished slots after a successful merge before skipping them.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant HarvestRenderer
  participant Git
  participant HarvestSettle
  participant CompareData
  HarvestRenderer->>Git: Read current base SHA
  Git-->>HarvestRenderer: Return base SHA
  HarvestRenderer->>Git: Merge winner at confirmed tip
  Git-->>HarvestRenderer: Return merge result
  HarvestRenderer->>HarvestSettle: Re-settle slots after successful merge
  HarvestRenderer->>CompareData: Read post-merge slot tips and dirty counts
  CompareData-->>HarvestRenderer: Return current slot state
  HarvestRenderer->>HarvestRenderer: Skip only unchanged finished slots
Loading
Merge Risk: ⚪ Minimal · up to 3ebed

The change tightens merge, validation, and timeout safeguards and adds tests and docs. No actionable merge-blocking risk was identified in the supplied context.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 55.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 14 files. (5 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main changes: merge-winner fixes, in-flight validation protection, timeout handling, and port-range configuration.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 55.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 14 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Steel-tech
Steel-tech merged commit 51cf119 into main Oct 15, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant