fix(ownership): configurable strategy-driven branch ownership detection#376
Merged
fix(ownership): configurable strategy-driven branch ownership detection#376
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wire ownership::fetch_commit_records + resolve_owner_from_records into collect_worktree_info and collect_branch_info, adding the owner: Option<BranchOwner> field alongside the existing owner_email during the transitional period. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
During the ownership transition, prune.rs was deriving owner_email from the resolved owner instead of tip-author like the collect_* paths. This caused inconsistent behavior for gone-branch stubs versus other entries. Align by using list::get_author_email_for_ref() to maintain consistent semantics until the legacy owner_email field is removed in Task 11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SortColumn::Owner now compares owners by name (case-insensitive), with ties broken by email. Updated the test helper to populate the `owner` field instead of `owner_email`, and updated test assertions accordingly. The `owner_email` field is retained for now; it will be removed in Task 11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… plumbing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delete the `owner_email` field from `WorktreeInfo`, the `get_author_email_for_ref` helper, and all call sites. Every consumer now reads the `owner: Option<BranchOwner>` field populated by the new ownership strategy instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update daft-list, daft-sync, configuration, and SKILL.md to reflect
strategy-based ownership: Owner column shows author name (not email),
JSON owner field is {name,email}|null, and daft.ownership.strategy
config key is documented with all six strategies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…se..branch is empty When `base..branch` yields no commits (e.g. freshly-created branches, branches merged into base), resolve owner via two fallbacks in order: 1. `base..<remote>/<branch>` — remote-tracking range. 2. Local reflog oldest entry — the committer identity that ran `git checkout -b` / `git worktree add -b` for this branch. Skips all fallbacks when `branch == base` (default branch) to avoid crediting the repo cloner as the default branch's owner. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces fragile tip-author-email ownership detection with a configurable strategy-driven resolver over the
base..branchcommit range.daft.ownership.strategy:tip,any,first,plurality,majority,recency-plurality(new default). The default gently weights recent commits (1/(k+1)) so a branch where you authored most commits is still yours even if a teammate wrote the tip — the original complaint that motivated this.(name, email)for stable ordering.{name, email}ornull). Breaking change — scripts consuming.[].owneras a string need to read.[].owner.emailor.[].owner.name.base..branch→base..<remote>/<branch>→ local reflog creator → blank. Base branches (wherebranch == base, e.g., master) intentionally skip all fallbacks and render blank, since ownership doesn't apply to shared trunks.Spec and plan are committed under
docs/superpowers/. All six strategies, the fallback chain, and parsing edge cases (tabs in author names, case-insensitive email collapse, nondeterministic tie-breaks) are covered by unit tests insrc/core/ownership.rsplus YAML scenarios intests/manual/scenarios/list/andtests/manual/scenarios/sync/.Test plan
mise run test:unit— 1062 lib tests passmise run test:integration— 394 scenarios, 1435 steps, full matrix (default/gitoxide × bash/yaml) greenmise run clippy— zero warningsmise run fmt:check— cleanmise run ci— full CI simulation greendaft listshows author names and base branches (master) show blank Ownerdaft list --jsonemits{name, email}objects (breaking change acknowledged)git config daft.ownership.strategy tip(or other values) and verify the Owner column changes accordingly🤖 Generated with Claude Code