{"id":43374201,"url":"https://github.com/dotsetlabs/whogitit","last_synced_at":"2026-02-02T06:18:25.515Z","repository":{"id":335694336,"uuid":"1146741801","full_name":"dotsetlabs/whogitit","owner":"dotsetlabs","description":"Track AI-generated code at line-level granularity. Know which lines were written by AI, modified by humans, and what prompts generated them. Git-native storage, automatic redaction, and Claude Code integration.","archived":false,"fork":false,"pushed_at":"2026-02-01T03:28:00.000Z","size":1086,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-01T03:47:25.081Z","etag":null,"topics":["ai-attribution","ai-coding-assistant","ai-generated-code","ai-tracking","anthropic","claude-code","cli","code-analysis","code-prevenance","code-review","code-transparency","compliance","developer-tools","devops","git-blame","git-hooks","git-notes","llm-tools","open-source","rust"],"latest_commit_sha":null,"homepage":"https://dotsetlabs.github.io/whogitit/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dotsetlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-31T15:54:29.000Z","updated_at":"2026-02-01T03:28:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dotsetlabs/whogitit","commit_stats":null,"previous_names":["dotsetlabs/ai-blame"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dotsetlabs/whogitit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotsetlabs%2Fwhogitit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotsetlabs%2Fwhogitit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotsetlabs%2Fwhogitit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotsetlabs%2Fwhogitit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dotsetlabs","download_url":"https://codeload.github.com/dotsetlabs/whogitit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotsetlabs%2Fwhogitit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29006902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T04:25:24.522Z","status":"ssl_error","status_checked_at":"2026-02-02T04:24:51.069Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-attribution","ai-coding-assistant","ai-generated-code","ai-tracking","anthropic","claude-code","cli","code-analysis","code-prevenance","code-review","code-transparency","compliance","developer-tools","devops","git-blame","git-hooks","git-notes","llm-tools","open-source","rust"],"created_at":"2026-02-02T06:18:23.649Z","updated_at":"2026-02-02T06:18:25.509Z","avatar_url":"https://github.com/dotsetlabs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# whogitit\n\nTrack AI-generated code at line-level granularity. Know exactly which lines were written by AI, which were modified by humans, and what prompts generated them.\n\n## Features\n\n- **Line-level attribution** - Track whether each line is AI-generated, human-modified, or original\n- **Prompt preservation** - Store the prompts that generated code alongside commits\n- **Three-way diff analysis** - Accurate attribution even when you edit AI code before committing\n- **Git-native storage** - Uses git notes that travel with your repository\n- **Claude Code integration** - Automatic capture via hooks\n- **GitHub Action** - PR comments showing AI attribution summaries with prompts\n- **Privacy protection** - Automatic redaction of API keys, passwords, and sensitive data\n- **Data retention policies** - Configurable age limits and auto-purge for compliance\n- **Audit logging** - Track deletions, exports, and configuration changes\n- **Export capabilities** - Bulk export attribution data as JSON or CSV\n\n## Installation\n\n### Quick Install (Recommended)\n\n**macOS / Linux:**\n```bash\ncurl -sSL https://github.com/dotsetlabs/whogitit/releases/latest/download/install.sh | sh\n```\n\n**Windows (PowerShell):**\n```powershell\nirm https://github.com/dotsetlabs/whogitit/releases/latest/download/install.ps1 | iex\n```\n\n### Via Cargo\n\n```bash\ncargo install whogitit\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/dotsetlabs/whogitit\ncd whogitit\ncargo install --path .\n```\n\n## Setup\n\n### 1. One-time global setup\n\nRun this once to configure Claude Code integration:\n\n```bash\nwhogitit setup\n```\n\nThis automatically:\n- Installs the capture hook to `~/.claude/hooks/`\n- Configures Claude Code's `settings.json` with the required hooks\n- No manual file copying or JSON editing needed\n\n### 2. Initialize each repository\n\n```bash\ncd your-project\nwhogitit init\n```\n\nThis installs git hooks that:\n- Attach attribution data to commits (post-commit)\n- Push git notes with your commits (pre-push)\n- Preserve notes during rebase/amend (post-rewrite)\n- Configure git to fetch notes automatically\n\n### 3. Verify your setup\n\n```bash\nwhogitit doctor\n```\n\nThis checks all configuration and shows any issues.\n\n### Manual setup (alternative)\n\nIf you prefer manual configuration, see [detailed installation docs](docs/src/getting-started/installation.md).\n\n### Push notes with commits\n\nGit notes are pushed automatically on `git push` after `whogitit init`. To push manually:\n\n```bash\ngit push origin refs/notes/whogitit\n```\n\n## CLI Commands\n\n### `whogitit blame \u003cfile\u003e`\n\nShow AI attribution for each line:\n\n```\n$ whogitit blame src/main.rs\n\n LINE   │ COMMIT  │ AUTHOR     │ SRC │ CODE\n─────────────────────────────────────────────────────────────────────────────────────\n    1   │ a1b2c3d │ Greg King  │  ─  │ use std::io;\n    2   │ d4e5f6g │ Greg King  │  ●  │ use anyhow::Result;\n    3   │ d4e5f6g │ Greg King  │  ●  │ use serde::{Deserialize, Serialize};\n    4   │ d4e5f6g │ Greg King  │  ◐  │ use chrono::Utc;  // modified\n    5   │ h8i9j0k │ Greg King  │  +  │ // Added by human\n─────────────────────────────────────────────────────────────────────────────────────\nLegend: ● AI (2) ◐ AI-modified (1) + Human (1) ─ Original (1)\nAI involvement: 60% (3 of 5 lines)\n```\n\nOptions:\n- `--revision \u003cref\u003e` - Blame at a specific revision\n- `--format json` - JSON output\n- `--ai-only` - Show only AI-generated lines\n- `--human-only` - Show only human-written lines\n\n### `whogitit show \u003ccommit\u003e`\n\nView attribution summary for a commit:\n\n```\n$ whogitit show HEAD\n\nCommit: d4e5f6g\nSession: 7f3a-4b2c-9d1e-8a7b\nModel: claude-opus-4-5-20251101\nStarted: 2026-01-30T14:23:17Z\n\nPrompts used:\n  #0: \"Add error handling with anyhow...\"\n  #1: \"Implement the serialize trait...\"\n\nFiles with AI changes:\n  src/auth.rs (25 AI, 3 modified, 2 human) - 45 total lines\n  src/main.rs (10 AI, 5 original) - 15 total lines\n\nSummary:\n  35 AI-generated lines\n  3 AI lines modified by human\n  2 human-added lines\n  5 original/unchanged lines\n```\n\n### `whogitit prompt \u003cfile:line\u003e`\n\nView the prompt that generated specific lines:\n\n```\n$ whogitit prompt src/main.rs:42\n\n╔════════════════════════════════════════════════════════════════════╗\n║  PROMPT #2 in session 7f3a-4b2c-9d1e...                            ║\n║  Model: claude-opus-4-5-20251101 | 2026-01-30T14:23:17Z            ║\n╠════════════════════════════════════════════════════════════════════╣\n║  Add JWT token generation with 24-hour expiration. Use the         ║\n║  jsonwebtoken crate. The function should take a user_id and        ║\n║  return a Result\u003cString\u003e.                                          ║\n╚════════════════════════════════════════════════════════════════════╝\n\nFiles affected by this prompt:\n  - src/auth.rs\n  - src/main.rs\n```\n\n### `whogitit summary`\n\nGenerate attribution summary for a commit range (useful for PRs):\n\n```bash\nwhogitit summary --base main --head HEAD\nwhogitit summary --base main --format markdown\nwhogitit summary --format json\n```\n\n### `whogitit status`\n\nCheck pending attribution changes (before commit):\n\n```\n$ whogitit status\n\nPending AI attribution:\n  Session: 7f3a-4b2c-9d1e-8a7b\n  Files: 3\n  Lines: 45\n\nRun 'git commit' to finalize attribution.\n```\n\n### `whogitit clear`\n\nDiscard pending changes without committing:\n\n```bash\nwhogitit clear\n```\n\n### `whogitit export`\n\nExport attribution data for multiple commits:\n\n```bash\nwhogitit export                           # JSON to stdout\nwhogitit export --format csv -o data.csv  # CSV to file\nwhogitit export --since 2026-01-01        # Filter by date\nwhogitit export --full-prompts            # Include full prompt text\n```\n\nOptions:\n- `--format json|csv` - Output format (default: json)\n- `--since \u003cdate\u003e` - Only commits after date (YYYY-MM-DD)\n- `--until \u003cdate\u003e` - Only commits before date\n- `-o, --output \u003cfile\u003e` - Output file (default: stdout)\n- `--full-prompts` - Include full prompt text (default: truncated)\n\n### `whogitit retention`\n\nManage data retention policies:\n\n```bash\nwhogitit retention config   # Show current retention settings\nwhogitit retention preview  # Preview what would be deleted\nwhogitit retention apply    # Dry-run deletion\nwhogitit retention apply --execute  # Actually delete old data\n```\n\n### `whogitit audit`\n\nView the audit log (tracks deletions, exports, config changes):\n\n```bash\nwhogitit audit                    # Show last 50 events\nwhogitit audit --limit 100        # Show more events\nwhogitit audit --since 2026-01-01 # Filter by date\nwhogitit audit --event-type delete # Filter by type\nwhogitit audit --json             # JSON output\n```\n\n### `whogitit redact-test`\n\nTest redaction patterns against text or files:\n\n```bash\nwhogitit redact-test --text \"text with api_key=secret123\"\nwhogitit redact-test --file config.txt\nwhogitit redact-test --list-patterns  # Show available patterns\nwhogitit redact-test --text \"...\" --matches-only  # Show matches without redacting\nwhogitit redact-test --text \"...\" --audit  # Show audit trail\n```\n\n### `whogitit annotations`\n\nGenerate annotations for GitHub Checks API (used by CI):\n\n```bash\nwhogitit annotations --base main --head HEAD\nwhogitit annotations --format json\nwhogitit annotations --consolidate file    # One annotation per file\nwhogitit annotations --consolidate lines   # Granular line annotations\nwhogitit annotations --max-annotations 50  # GitHub API limit\n```\n\nOptions:\n- `--base \u003ccommit\u003e` - Base commit (exclusive)\n- `--head \u003ccommit\u003e` - Head commit (default: HEAD)\n- `--format github-checks|json` - Output format\n- `--consolidate auto|file|lines` - Consolidation mode (default: auto)\n- `--consolidate-threshold \u003c0.0-1.0\u003e` - AI coverage threshold for auto mode (default: 0.7)\n- `--min-lines \u003cn\u003e` - Minimum AI lines for annotation (default: 1)\n- `--max-annotations \u003cn\u003e` - Maximum annotations (default: 50)\n- `--ai-only` - Only annotate pure AI lines\n\n### `whogitit copy-notes`\n\nCopy attribution between commits (useful after cherry-pick):\n\n```bash\nwhogitit copy-notes \u003csource-sha\u003e \u003ctarget-sha\u003e\nwhogitit copy-notes abc123 def456 --dry-run\n```\n\nNote: For rebase and amend, the post-rewrite hook automatically preserves notes. Use `copy-notes` for cherry-pick or manual recovery.\n\n### `whogitit pager`\n\nAnnotate git diff output with AI attribution (use as git pager):\n\n```bash\n# Configure as git pager\ngit config --global core.pager \"whogitit pager\"\n\n# Or use with aliases\ngit config --global alias.ai-diff '!git diff | whogitit pager --no-pager'\ngit diff | whogitit pager\n\n# Options\nwhogitit pager --verbose     # Show model, timestamps\nwhogitit pager --no-color    # Disable colors\nwhogitit pager --no-pager    # Output directly to stdout\n```\n\nSee [Git Integration](docs/src/usage/git-integration.md) for more details.\n\n## Configuration\n\nCreate `.whogitit.toml` in your repository root to configure privacy and retention:\n\n```toml\n[privacy]\n# Enable audit logging for compliance\naudit_log = true\n# Disable specific builtin patterns\ndisabled_patterns = [\"EMAIL\"]\n\n# Additional custom redaction patterns\n[[privacy.custom_patterns]]\nname = \"INTERNAL_ID\"\npattern = \"INTERNAL-\\\\d+\"\ndescription = \"Internal tracking IDs\"\n\n[retention]\n# Delete attribution older than 365 days\nmax_age_days = 365\n# Keep at least 100 commits regardless of age\nmin_commits = 100\n# Never delete attribution for these refs\nretain_refs = [\"refs/heads/main\"]\n# Auto-purge on commit (default: false)\nauto_purge = false\n```\n\n## GitHub Action\n\nAdd AI attribution summaries to pull requests automatically.\n\n### Setup\n\nCreate `.github/workflows/ai-attribution.yml`:\n\n```yaml\nname: AI Attribution Summary\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened]\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  analyze:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n          ref: ${{ github.event.pull_request.head.sha }}\n\n      - name: Fetch git notes\n        run: git fetch origin refs/notes/whogitit:refs/notes/whogitit || true\n        continue-on-error: true\n\n      - name: Setup Rust\n        uses: dtolnay/rust-toolchain@stable\n\n      - name: Cache cargo\n        uses: actions/cache@v4\n        with:\n          path: |\n            ~/.cargo/bin/\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n            target/\n          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}\n\n      - name: Build whogitit\n        run: cargo build --release\n\n      # ... analysis and comment posting steps\n      # See .github/workflows/ai-attribution.yml for full implementation\n```\n\n### Example PR Comment\n\nThe action posts a comment like this:\n\n---\n\n## 🤖🤖 AI Attribution Summary\n\nThis PR adds **+200** lines with AI attribution across **3** files.\n\n### Additions Breakdown\n\n| Metric | Lines | % of Additions |\n|--------|------:|--------------:|\n| 🟢 AI-generated | +145 | 72.5% |\n| 🟡 AI-modified by human | +12 | 6.0% |\n| 🔵 Human-written | +43 | 21.5% |\n| **Total additions** | **+200** | **100%** |\n\n**AI involvement: 78.5%** of additions are AI-generated\n\n### Files Changed\n\n| File | +Added | AI | Human | AI % | Status |\n|------|-------:|---:|------:|-----:|--------|\n| `src/auth.rs` | +80 | 72 | 8 | 90% | New |\n| `src/main.rs` | +45 | 32 | 13 | 71% | Modified |\n| `src/jwt.rs` | +75 | 53 | 22 | 71% | New |\n\n### Commits with AI Attribution\n\n| Commit | Message | AI | Modified | Human | Files |\n|--------|---------|---:|--------:|------:|------:|\n| `abc1234` | Add user authentication | 72 | 3 | 5 | 2 |\n| `def5678` | Implement JWT tokens | 85 | 9 | 26 | 2 |\n\n### Prompts Used (2)\n\n**Prompt 1** (src/auth.rs, src/main.rs)\n\u003cdetails\u003e\n\u003csummary\u003eAdd user authentication with bcrypt password hashing...\u003c/summary\u003e\n\n```\nAdd user authentication with bcrypt password hashing. Create a User struct\nwith email and password_hash fields. Implement register and login functions\nthat return Result types.\n```\n\u003c/details\u003e\n\n**Prompt 2** (src/jwt.rs)\n\u003cdetails\u003e\n\u003csummary\u003eImplement JWT token generation with 24-hour expiration...\u003c/summary\u003e\n\n```\nImplement JWT token generation with 24-hour expiration. Use the jsonwebtoken\ncrate. The function should take a user_id and return a Result\u003cString\u003e.\n```\n\u003c/details\u003e\n\n---\n\n## How It Works\n\n### Three-Way Diff Analysis\n\nwhogitit captures complete file snapshots during editing, enabling accurate attribution:\n\n1. **Original** - Content before any AI edits\n2. **AI Snapshots** - Content after each AI edit\n3. **Final** - Content at commit time\n\nThis allows tracking even when you modify AI-generated code before committing.\n\n### Line Attribution Types\n\n| Source | Symbol | Description |\n|--------|--------|-------------|\n| AI | `●` | Generated by AI, unchanged |\n| AIModified | `◐` | Generated by AI, then edited by human |\n| Human | `+` | Added by human after AI edits |\n| Original | `─` | Existed before AI session |\n| Unknown | `?` | Could not determine source |\n\n### Data Flow\n\n```\nClaude Code (Edit/Write tools)\n         │\n         ├─► PreToolUse: Save file state\n         ├─► PostToolUse: Capture change + prompt\n         │\n         ▼\nPending Buffer (.whogitit-pending.json)\n         │\n         ▼ git commit\n         │\nThree-Way Analysis → Git Notes (refs/notes/whogitit)\n```\n\n## Storage\n\nAttribution is stored in git notes (`refs/notes/whogitit`), which:\n- Travel with repository when pushed/fetched\n- Don't clutter commit history\n- Can be inspected with standard git commands\n\n```bash\n# View raw attribution\ngit notes --ref=whogitit show HEAD\n\n# List all attributed commits\ngit notes --ref=whogitit list\n```\n\n## Privacy\n\nPrompts are automatically scanned and redacted for:\n\n- API keys (`api_key`, `apikey`, `secret`, `token`)\n- AWS credentials (`AKIA...`)\n- Private keys (`-----BEGIN.*PRIVATE KEY-----`)\n- Bearer tokens\n- GitHub tokens (`ghp_`, `gho_`, `ghs_`, `ghr_`)\n- Email addresses\n- Passwords\n\nSensitive data is replaced with `[REDACTED]` before storage.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotsetlabs%2Fwhogitit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdotsetlabs%2Fwhogitit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotsetlabs%2Fwhogitit/lists"}