Skip to content

Name the commits' real authors in git dockets - #15

Merged
kridaydave merged 1 commit into
mainfrom
k5/pass-oot-git-authors-revrange
Oct 6, 2026
Merged

kridaydave merged 1 commit into
mainfrom
k5/pass-oot-git-authors-revrange

Conversation

@kridaydave

Copy link
Copy Markdown
Contributor

Problem

GitAdapter::authors (src/adapter/git.rs:108) passed the revision range after --:

.args(["log", "--format=%an", "--", rev_range])

After -- git reads its argument as a pathspec, not a revision range. A range is not a path, so nothing matches and git exits 0. The call therefore returned an empty author list instead of failing, and the error branch at git.rs:115 never fired.

adjudicate_3way (git.rs:210-213) reads an empty list as unknown provenance and substitutes the literal @git-author. So every git-authored docket carried a fabricated author instead of the commits' real authors. Nothing in the suite covered authors; grep authors tests/git_adapter_test.rs returned nothing.

Proof it was broken

Run against a real repo whose HEAD commit is authored by Dana Feature <dana@example.com>:

$ git log --format=%an -- "HEAD~1..HEAD"      # the old form
                                            # exit 0, zero lines
$ git log --format=%an "HEAD~1..HEAD" --    # the new form
Dana Feature

The old form's empty output is what drove the @git-author fallback.

Change

Range moved before --. One behavioral line, plus a comment saying why the position matters so it is not "tidied" back.

The new test commits as a named author and asserts the docket names them, so the regression cannot come back silently.

Verification

  • cargo check -p oot --all-targets → Finished, exit 0.
  • cargo fmt --all -- --check → clean, exit 0.
  • Red-then-green proven by executing the exact authors() code path standalone against a real repo, since cargo test cannot run on the audit box: old form → [] → docket ["@git-author"], assertion FAILS; new form → ["Dana Feature"].

Full suite and clippy verdict come from CI.

src/adapter/git.rs         |  5 +++-
tests/git_adapter_test.rs  | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 1 deletion(-)

Not shipped

Findings from the same pass, left alone as separate concerns. No code changed for them.

  • src/visibility.rs:207-212 — VisibilityPolicy::check re-implements private-branch matching inline with a bare contains(pb), while branch_is_private (visibility.rs:107) does segment-aware matching. With private_branches = ["main"], a change named domain-model is cloaked by check but not private per branch_is_private. Adjudication and export disagree. Duplicated policy, so worth one source of truth, but the fix changes which changes get cloaked and needs the owner's call on the intended semantics.
  • src/store.rs:3989 — message_names_private_path hand-rolls private-path matching and has no wildcard branch, so a policy using *.pem never triggers the message-leak warning.
  • Dead code with zero callers in src/ and tests/: get_head_branch (store.rs:183), has_ref (store.rs:414), resolve_change_id (adapter/jj.rs:138), embargo_verify (store.rs:3177).
  • src/adapter/jj.rs:217-220 — the conflict-marker predicate looks unreachable for real jj and git markers. Could not settle it here: the jj v0.44 musl binary SIGBUSes under proot, so the conflicting-merge path never ran. tests/jj_adapter_test.rs:223 asserts the opposite and CI installs jj and is green, which argues against the finding. Unverified either way.
  • CONTRIBUTING.md:51 says a dispute has four fields; Dispute (src/dispute.rs:44) has five, the fifth being detail. CONTRIBUTING.md:42 shows scope: in the docket contract; the renderer emits intent: (src/dispute.rs:223), and scope survives only as a serde alias.
  • README.md:23 and CONTRIBUTING.md:15 name the policy schema as private-to, embargo-until, public. None of those keys exist; VisibilityPolicy (src/visibility.rs:18) has private_paths, embargo_until, private_branches, resign_key_id, embargo_recipients. Neither struct sets deny_unknown_fields, so a policy written from the README parses into defaults and reads as enforcement while doing nothing.
  • README.md:60 says exit 0 is adjudicated and everything else nonzero so CI can gate on it. --docket (src/main.rs:268-272) and oot docket (src/main.rs:771-776) return SUCCESS whatever the stored verdict.

GitAdapter::authors passed the revision range after `--`, so git read it
as a pathspec rather than a range. That matched no path and exited 0, so
the call returned an empty list instead of failing.

adjudicate_3way treats an empty list as "unknown author" and substitutes
the literal @git-author, so every git docket recorded a fabricated
provenance rather than the commits' actual authors. The error branch at
git.rs:115 never fired either, because git exited successfully.

Move the range before `--`. Adds test_git_adapter_3way_reports_real_commit_authors,
which commits as a named author and asserts the docket names them.

src/adapter/git.rs            |  5 +++-
tests/git_adapter_test.rs     | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 1 deletion(-)
@kridaydave
kridaydave merged commit 38e2138 into main Oct 6, 2026
5 of 10 checks passed
@kridaydave
kridaydave deleted the k5/pass-oot-git-authors-revrange branch October 6, 2026 03:03
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