docs: worktree-ownership convention + worktree-status helper - #61
Conversation
…lper Multiple agents work in parallel worktrees, but neither git nor the Claude UI records which agent owns which worktree. Add an AGENTS.md "Worktree ownership" section describing the local-only .worktree-owner marker (git-ignored via .gitignore), the pre-delete safety checks (lsof / merged / lock), and pointing at docs/inflight.md for the branch->work map. Add bin/worktree-status.sh: prints each worktree's marker fields plus live lsof holders — the "who's on what" view the UI lacks. Ignore the marker in .gitignore so all contributors and CI honor it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
❌ Duplicate Code ReportTwo engines run in parallel for cross-validation. Each has its own thresholds tuned to its baseline - the real safety net is the per-engine "max increase vs base" check. ✅ PMD CPD
No new clones introduced by this PR. ❌ jscpd (language-agnostic)
No new clones introduced by this PR. Powered by astubbs/duplicate-code-cross-check |
✅ SpotBugs ReportNo bugs found (new bugs only — baseline from base branch excluded). |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #61 +/- ##
============================================
- Coverage 77.15% 77.13% -0.03%
- Complexity 75 1153 +1078
============================================
Files 82 82
Lines 4190 4190
Branches 386 386
============================================
- Hits 3233 3232 -1
- Misses 765 766 +1
Partials 192 192
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
❌ Mutation Testing (PIT) ReportPIT did not produce a report. Most commonly this means a test failed in the baseline (PIT runs all tests unmodified first to establish green) and PIT aborted before mutating. See the "Run PIT mutation testing" step logs for the failing test, then either fix it or add it to |
BrokerIntegrationTest.ensureTopic duplicated KafkaClientUtils's topic creation but waited with .get(1, TimeUnit.SECONDS). On a cold/loaded CI broker, createTopics regularly takes >1s, so the TimeoutException was rethrown as a hard failure — flaking the *required* Integration Tests check and blocking otherwise-green PRs (e.g. #56, #61). Consolidate onto one blocking helper in the canonical util: - KafkaClientUtils.createTopic(name, partitions) + shared private createTopicsBlocking(): waits unbounded (like the other integration admin waits) and tolerates only TopicExistsException, propagating any other failure instead of swallowing all ExecutionExceptions. - ensureTopic() and createTopics(int) both delegate to it — one implementation, no drift. Also make the DRY expectation explicit so this doesn't recur: - AGENTS.md "Testing": search/extend KafkaClientUtils & BrokerIntegration Test before adding test helpers; check docs/solutions/ for prior art. - docs/solutions/test-issues/: learnings entry for the flake + fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BrokerIntegrationTest.ensureTopic duplicated KafkaClientUtils's topic creation but waited with .get(1, TimeUnit.SECONDS). On a cold/loaded CI broker, createTopics regularly takes >1s, so the TimeoutException was rethrown as a hard failure — flaking the *required* Integration Tests check and blocking otherwise-green PRs (e.g. #56, #61). Consolidate onto one blocking helper in the canonical util: - KafkaClientUtils.createTopic(name, partitions) + shared private createTopicsBlocking(): waits unbounded (like the other integration admin waits) and tolerates only TopicExistsException, propagating any other failure instead of swallowing all ExecutionExceptions. - ensureTopic() and createTopics(int) both delegate to it — one implementation, no drift. Also make the DRY expectation explicit so this doesn't recur: - AGENTS.md "Testing": search/extend KafkaClientUtils & BrokerIntegration Test before adding test helpers; check docs/solutions/ for prior art. - docs/solutions/test-issues/: learnings entry for the flake + fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#63) * fix(test): consolidate topic creation to kill flaky Integration Tests BrokerIntegrationTest.ensureTopic duplicated KafkaClientUtils's topic creation but waited with .get(1, TimeUnit.SECONDS). On a cold/loaded CI broker, createTopics regularly takes >1s, so the TimeoutException was rethrown as a hard failure — flaking the *required* Integration Tests check and blocking otherwise-green PRs (e.g. #56, #61). Consolidate onto one blocking helper in the canonical util: - KafkaClientUtils.createTopic(name, partitions) + shared private createTopicsBlocking(): waits unbounded (like the other integration admin waits) and tolerates only TopicExistsException, propagating any other failure instead of swallowing all ExecutionExceptions. - ensureTopic() and createTopics(int) both delegate to it — one implementation, no drift. Also make the DRY expectation explicit so this doesn't recur: - AGENTS.md "Testing": search/extend KafkaClientUtils & BrokerIntegration Test before adding test helpers; check docs/solutions/ for prior art. - docs/solutions/test-issues/: learnings entry for the flake + fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * review: bound topic-create wait to 60s + fix import ordering Address Claude review on #63: - createTopicsBlocking now waits with a generous 60s bound (was unbounded) and throws a clear "timed out waiting for the broker to create topics ..." message, so a genuinely unresponsive broker fails fast/diagnosably instead of hanging until the outer CI timeout. 60s is far above the sub-second a healthy broker needs (the old 1s was the flake). Constant-named for intent. - Move the pl.tlinkowski UniLists import out of the org.apache.kafka run to restore alphabetical grouping. - Update inflight.md + docs/solutions to say "60s bound" not "unbounded". Finding #3 (createTopics(int) now tolerates TopicExistsException) left as-is: those topic names carry a random suffix so collisions can't occur. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Adds a convention so parallel agents/sessions can tell who is working in which git worktree — something neither git nor the Claude UI surfaces.
.worktree-ownermarker — a local-only file at each worktree root recordingowner,status,branch,pr, and a briefwork:line. Git-ignored (added to.gitignore), so it's coordination state, never repo content.bin/worktree-status.sh— prints every worktree with its marker fields plus live process holders (lsof) — the "who's on what" view the UI lacks. Run before starting parallel work or before deleting a worktree.lsofholder / merged / optionalgit worktree lock), and points atdocs/inflight.mdfor the branch→work map.Why
While juggling several in-flight worktrees, we nearly removed one that a GUI (and separately, another agent's shell) was actively holding. This makes ownership explicit and gives a one-command safety check.
Notes
bin/worktree-status.sh'slsofon the main checkout is naturally noisy (it recurses into nested.claude/worktrees/*); per-worktree output is clean.🤖 Generated with Claude Code