Skip to content

fix(hooks): trust fingerprinting, stale entry protection, and prune improvements#278

Merged
avihut merged 4 commits intomasterfrom
fix/hooks
Mar 8, 2026
Merged

fix(hooks): trust fingerprinting, stale entry protection, and prune improvements#278
avihut merged 4 commits intomasterfrom
fix/hooks

Conversation

@avihut
Copy link
Owner

@avihut avihut commented Mar 7, 2026

Summary

  • Trust fingerprinting: Store the remote URL when trusting a repository, and verify it at hook execution time. If a different repository is cloned to the same path, trust is downgraded to prompt with a warning — preventing silent trust inheritance
  • Stale entry removal on clone: When cloning without --trust-hooks to a path that already has a trust entry, the stale entry is removed since the old repo was replaced
  • Fingerprint backfill: The prune command (and background auto-prune) now backfills fingerprints for existing entries that lack them
  • Path canonicalization fix: Trust database lookups now canonicalize paths consistently to prevent mismatches
  • Completions: Added path completion for hooks trust/deny/reset subcommands

Test plan

  • mise run fmt — clean
  • mise run clippy — zero warnings
  • mise run test:unit — 414 pass, 0 fail
  • Pre-commit hooks pass (prettier, fmt, clippy, man/cli-docs verify)
  • Manual: clone with --trust-hooks → verify trust.json has fingerprint field
  • Manual: delete repo, clone different repo to same path → verify hooks skipped with mismatch warning
  • Manual: daft hooks trust list → verify fingerprint shown
  • Manual: old trust entries (no fingerprint) still work

Fixes #278

🤖 Generated with Claude Code

avihut and others added 4 commits March 7, 2026 12:03
Add `daft hooks trust prune` to remove stale entries from the trust
database (paths that no longer exist on disk). Also runs automatically
in the background once per 24 hours using the same fire-and-forget
detached process pattern as the update check.

Disable auto-pruning with `git config --global daft.hooks.trustPrune false`
or `DAFT_NO_TRUST_PRUNE=1`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shell completions for `daft hooks`, `daft hooks status`, `daft hooks
trust`, `daft hooks prompt`, and `daft hooks deny` now complete
directory paths for the [PATH] argument. Also adds flag completions
for these subcommands and the missing -v/--verbose flag for hooks run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…smatches

Clone stored relative paths (e.g. "tax-analyzer/.git") in the trust
database, but all lookups used canonicalized absolute paths from
get_git_common_dir(). This caused --trust-hooks to appear ineffective:
the entry existed in trust list but was never found during lookup.

Fix by canonicalizing paths in all TrustDatabase methods (get, set,
remove, has_explicit_trust) so both sides always use consistent
absolute paths. Also canonicalize git_dir in clone after bare clone
succeeds, ensuring hook execution context uses the canonical path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a repository is trusted, store the remote URL as a fingerprint.
On hook execution, verify the fingerprint matches the current remote —
a mismatch (e.g., different repo cloned to same path) downgrades trust
to prompt with a warning. Legacy entries without fingerprints continue
to work unchanged.

Also removes stale trust entries when cloning without --trust-hooks to
a path that already has a trust entry, and backfills fingerprints for
existing entries during prune (both manual and background).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@avihut avihut added this to the v1.1.0 milestone Mar 8, 2026
@avihut avihut added bug Something isn't working fix Bug fix labels Mar 8, 2026
@avihut avihut self-assigned this Mar 8, 2026
@avihut avihut merged commit 1f6fd5e into master Mar 8, 2026
6 checks passed
@avihut avihut deleted the fix/hooks branch March 8, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant