$npx -y skills add gadievron/raptor --skill github-evidence-kitGenerate, export, load, and verify forensic evidence from GitHub sources. Use when creating verifiable evidence objects from GitHub API, GH Archive, Wayback Machine, local git repositories, or security vendor reports. Handles evidence storage, querying, and re-verification agains
| 1 | # GH Evidence Kit |
| 2 | |
| 3 | **Purpose**: Create, store, and verify forensic evidence from GitHub-related public sources and local git repositories. |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | - Creating verifiable evidence objects from GitHub activity |
| 8 | - **Local git forensics** - analyzing cloned repositories, dangling commits, reflog |
| 9 | - Exporting evidence collections to JSON for sharing/archival |
| 10 | - Loading and re-verifying previously collected evidence |
| 11 | - Recovering deleted GitHub content (issues, PRs, commits) from GH Archive |
| 12 | - Tracking IOCs (Indicators of Compromise) with source verification |
| 13 | |
| 14 | ## Quick Start |
| 15 | |
| 16 | ```python |
| 17 | from src.collectors import GitHubAPICollector, LocalGitCollector, GHArchiveCollector |
| 18 | from src import EvidenceStore |
| 19 | |
| 20 | # Create collectors for different sources |
| 21 | github = GitHubAPICollector() |
| 22 | local = LocalGitCollector("/path/to/repo") |
| 23 | archive = GHArchiveCollector() |
| 24 | |
| 25 | # Collect evidence from GitHub API |
| 26 | commit = github.collect_commit("aws", "aws-toolkit-vscode", "678851b...") |
| 27 | pr = github.collect_pull_request("aws", "aws-toolkit-vscode", 7710) |
| 28 | |
| 29 | # Collect evidence from local git (first-class forensic source) |
| 30 | local_commit = local.collect_commit("HEAD") |
| 31 | dangling = local.collect_dangling_commits() # Forensic gold! |
| 32 | |
| 33 | # Store and export |
| 34 | store = EvidenceStore() |
| 35 | store.add(commit) |
| 36 | store.add(pr) |
| 37 | store.add(local_commit) |
| 38 | store.add_all(dangling) |
| 39 | store.save("evidence.json") |
| 40 | |
| 41 | # Verify all evidence against original sources |
| 42 | is_valid, errors = store.verify_all() |
| 43 | ``` |
| 44 | |
| 45 | ## Collectors |
| 46 | |
| 47 | ### GitHubAPICollector |
| 48 | |
| 49 | Collects evidence from the live GitHub API. |
| 50 | |
| 51 | ```python |
| 52 | from src.collectors import GitHubAPICollector |
| 53 | |
| 54 | collector = GitHubAPICollector() |
| 55 | ``` |
| 56 | |
| 57 | | Method | Returns | |
| 58 | |--------|---------| |
| 59 | | `collect_commit(owner, repo, sha)` | CommitObservation | |
| 60 | | `collect_issue(owner, repo, number)` | IssueObservation | |
| 61 | | `collect_pull_request(owner, repo, number)` | IssueObservation | |
| 62 | | `collect_file(owner, repo, path, ref)` | FileObservation | |
| 63 | | `collect_branch(owner, repo, branch_name)` | BranchObservation | |
| 64 | | `collect_tag(owner, repo, tag_name)` | TagObservation | |
| 65 | | `collect_release(owner, repo, tag_name)` | ReleaseObservation | |
| 66 | | `collect_forks(owner, repo)` | list[ForkObservation] | |
| 67 | |
| 68 | ### LocalGitCollector (First-Class Forensics) |
| 69 | |
| 70 | Collects evidence from local git repositories. Essential for forensic analysis of cloned repos. |
| 71 | |
| 72 | ```python |
| 73 | from src.collectors import LocalGitCollector |
| 74 | |
| 75 | collector = LocalGitCollector("/path/to/cloned/repo") |
| 76 | |
| 77 | # Collect a specific commit |
| 78 | commit = collector.collect_commit("HEAD") |
| 79 | commit = collector.collect_commit("abc123") |
| 80 | |
| 81 | # Find dangling commits (not reachable from any ref) |
| 82 | # This is forensic gold - reveals force-pushed or deleted commits! |
| 83 | dangling = collector.collect_dangling_commits() |
| 84 | for commit in dangling: |
| 85 | print(f"Found dangling: {commit.sha[:8]} - {commit.message}") |
| 86 | ``` |
| 87 | |
| 88 | | Method | Returns | |
| 89 | |--------|---------| |
| 90 | | `collect_commit(sha)` | CommitObservation | |
| 91 | | `collect_dangling_commits()` | list[CommitObservation] | |
| 92 | |
| 93 | ### GHArchiveCollector |
| 94 | |
| 95 | Collects and recovers evidence from GH Archive (BigQuery). Requires credentials. |
| 96 | |
| 97 | ```python |
| 98 | from src.collectors import GHArchiveCollector |
| 99 | |
| 100 | collector = GHArchiveCollector() |
| 101 | |
| 102 | # Query events by timestamp (YYYYMMDDHHMM format) |
| 103 | events = collector.collect_events( |
| 104 | timestamp="202507132037", |
| 105 | repo="aws/aws-toolkit-vscode" |
| 106 | ) |
| 107 | |
| 108 | # Recover deleted content |
| 109 | deleted_issue = collector.recover_issue("aws/aws-toolkit-vscode", 123, "2025-07-13T20:30:24Z") |
| 110 | deleted_pr = collector.recover_pr("aws/aws-toolkit-vscode", 7710, "2025-07-13T20:30:24Z") |
| 111 | deleted_commit = collector.recover_commit("aws/aws-toolkit-vscode", "678851b", "2025-07-13T20:30:24Z") |
| 112 | force_pushed = collector.recover_force_push("aws/aws-toolkit-vscode", "2025-07-13T20:30:24Z") |
| 113 | ``` |
| 114 | |
| 115 | | Method | Returns | |
| 116 | |--------|---------| |
| 117 | | `collect_events(timestamp, repo, actor, event_type)` | list[Event] | |
| 118 | | `recover_issue(repo, number, timestamp)` | IssueObservation | |
| 119 | | `recover_pr(repo, number, timestamp)` | IssueObservation | |
| 120 | | `recover_commit(repo, sha, timestamp)` | CommitObservation | |
| 121 | | `recover_force_push(repo, timestamp)` | CommitObservation | |
| 122 | |
| 123 | ### WaybackCollector |
| 124 | |
| 125 | Collects archived snapshots from the Wayback Machine. |
| 126 | |
| 127 | ```python |
| 128 | from src.collectors import WaybackCollector |
| 129 | |
| 130 | collector = WaybackCollector() |
| 131 | |
| 132 | # Get all snapshots for a URL |
| 133 | snapshots = collector.collect_snapshots("https://github.com/owner/repo") |
| 134 | |
| 135 | # With date filtering |
| 136 | snapshots = collector.collect_snapshots( |
| 137 | "https://github.com/owner/repo", |
| 138 | from_date="20250101", |
| 139 | to_date="20250731" |
| 140 | ) |
| 141 | |
| 142 | # Fetch actual content of a |