Gittensor Miner Guide
A complete guide for miners on Bittensor Subnet 74 (SN74). Learn how the scoring works and how to maximize your TAO rewards.
1. What is Gittensor?
Gittensor is a Bittensor subnet that pays you TAO cryptocurrency for contributing to open-source projects on GitHub.
The concept is simple:
- You make pull requests to whitelisted open-source repositories
- Validators automatically detect and score your merged PRs
- You earn TAO proportional to the quality and impact of your code
You don't need to run any mining software. You just need a Bittensor wallet, a GitHub account, and the ability to write code that gets merged.
2. How It Works (Big Picture)
3. Getting Started
Prerequisites
- A Bittensor wallet with a registered hotkey on subnet 74
- A GitHub account (must be older than minimum age requirement)
- A GitHub Personal Access Token (PAT) with repo read access
Register Your PAT
# Install the CLI
pip install gittensor
# Broadcast your GitHub PAT to all validators
gitt miner post --wallet <your-wallet-name> --hotkey <your-hotkey-name>
# Verify validators received it
gitt miner check --wallet <your-wallet-name> --hotkey <your-hotkey-name>
After this, start making PRs. The system will automatically detect and score them.
Important Rules
- One GitHub account per miner UID. If multiple UIDs share the same GitHub account, ALL of them get zeroed out (sybil detection).
- Your GitHub identity is pinned to your hotkey. Once you register, that GitHub account is permanently associated with your hotkey.
- If you re-register a UID with a new hotkey, you must run
gitt miner postagain.
4. The Eligibility Gate
Two Requirements
| Requirement | Threshold | How It's Calculated |
|---|---|---|
| Minimum valid merged PRs | 5 | Count of merged PRs where token_score >= 5 |
| Minimum credibility | 75% | merged_count / (merged_count + closed_count - 1) |
Credibility Formula
mulligan = 1 (your first closed PR is forgiven entirely)
- Only PRs within the 35-day lookback window count.
- Open PRs do NOT affect credibility.
Examples
| Merged | Closed | Credibility | Eligible? |
|---|---|---|---|
| 5 | 0 | 5/(5+0) = 100% | Yes |
| 5 | 1 | 5/(5+0) = 100% | Yes (mulligan forgives the 1 closed) |
| 5 | 2 | 5/(5+1) = 83% | Yes |
| 5 | 3 | 5/(5+2) = 71% | No — below 75% |
| 3 | 0 | 100% | No — below 5 valid merged PRs |
| 10 | 5 | 10/(10+4) = 71% | No — below 75% |
| 10 | 4 | 10/(10+3) = 77% | Yes |
- Get your first 5 quality merged PRs as fast as possible. Until then, you earn nothing.
- Don't submit throwaway PRs. Every closed/rejected PR (after the first one) hurts your credibility.
- A "valid" PR means
token_score >= 5. Trivial PRs (typo fixes, single-line config changes) may not meet this.
5. How Your PRs Are Scored
The AST-Based Scoring System
Gittensor doesn't just count lines of code. It uses tree-sitter to parse your code into an Abstract Syntax Tree (AST) and scores individual nodes.
Step 1: Parse both versions. The validator fetches the file content before and after your PR (using merge-base, not branch tip, so only your actual changes are counted).
Step 2: Compute tree diff. It compares the ASTs and finds:
- Added nodes: things in the new code that weren't in the old code
- Deleted nodes: things in the old code that aren't in the new code
- Both count toward your score (refactoring/removing code is valued too)
Step 3: Score each node. Every AST node has a weight:
Structural Nodes (High Value)
These represent the "skeleton" of your code:
| Node Type | Weight | What It Is |
|---|---|---|
class_declaration | 2.5 | New class definition |
function_declaration | 2.5 | New function declaration |
function_definition | 2.0 | New function definition |
method_definition | 2.0 | New method |
interface_declaration | 1.75 | New interface |
struct_definition | 1.75 | New struct |
async_function_definition | 1.5 | New async function |
trait_definition | 1.5 | New trait |
arrow_function | 0.75 | Arrow/lambda function |
with_statement | 0.6 | Context manager |
call_expression | 0.55 | Function call |
for_statement | 0.5 | For loop |
lambda_expression | 0.5 | Lambda |
switch_statement | 0.4 | Switch/case |
while_statement | 0.4 | While loop |
decorator | 0.4 | Decorator |
return_statement | 0.35 | Return |
if_statement | 0.35 | If statement |
Leaf Nodes (Lower Value)
These are the actual tokens in your code:
| Node Type | Weight | What It Is |
|---|---|---|
assignment_operator | 0.2 | =, +=, etc. |
self / this | 0.15 | Self references |
type_identifier | 0.15 | Type names |
comparison_operator | 0.15 | ==, <, etc. |
boolean / true / false | 0.1 | Boolean values |
operator | 0.1 | Operators |
identifier | 0.07 | Variable names |
string_literal | 0.05 | String values |
integer / float | 0.03 | Numbers |
string_content | 0.02 | String inner text |
comment (all types) | 0.0 | Comments score ZERO |
- Functions and classes are the highest-scoring elements (2.0-2.5 per node)
- Comments are literally worth zero — don't pad PRs with comments
- Identifiers (variable names) are only 0.07 each — renaming variables across a file doesn't earn much
- Both additions and deletions count — meaningful refactoring that removes code is valued
Non-Code Files
Files with these extensions use simpler line-count scoring (capped at 300 lines):
| Extension | Weight |
|---|---|
Markdown (.md, .mdx) | 0.08 |
JSON (.json) | 0.1 |
YAML (.yaml, .yml) | 1.0 |
Config files (.cfg, .conf, .ini) | 0.5 |
| CSV / TSV | 0.1 |
Documentation-only PRs score very little.
Test Files
Files detected as test files get a 0.05 weight multiplier — test code scores 95% less than production code.
Detection: files in tests/, test/, __tests__/ directories, or files named test_*.py, *.test.js, *.spec.ts, etc. Also Rust #[cfg(test)] and Zig test blocks.
Other Rules
- Deleted files (status
removed) score zero. - Files larger than 1 MB are skipped entirely (score 0).
6. The Full Scoring Formula
For each merged PR:
code_density = min(token_score / total_lines_changed, 3.0)
initial_base_score = 30 × code_density (0 if token_score < 5)
contribution_bonus = min(1.0, total_token_score / 2000) × 30
base_score = initial_base_score + contribution_bonus
Your total score = sum of all earned_scores − total collateral from open PRs
7. Multipliers Explained
Repo Weight Multiplier
Each whitelisted repo has a weight. This is the single biggest multiplier.
- bitcoin/bitcoin: 100.0 (the highest)
- opentensor/subtensor: 71.03
- entrius/gittensor: 53.48
- Most Bronze repos: 0.12 - 0.20
- Median repo: 0.17
A PR to bitcoin/bitcoin scores ~588x more than a PR to a typical Bronze repo (weight 0.17).
Time Decay Multiplier
PRs lose value over time after being merged:
| Days Since Merge | Multiplier |
|---|---|
| 0 - 0.5 days | 1.00 (grace period) |
| 1 day | ~0.98 |
| 5 days | ~0.88 |
| 10 days (midpoint) | ~0.50 |
| 15 days | ~0.12 |
| 20 days | ~0.06 |
| 25+ days | ~0.05 (floor) |
| 35+ days | Not scored (outside lookback) |
Formula: sigmoid curve with 10-day midpoint, 12-hour grace period, 5% floor.
Credibility Multiplier
Equal to your credibility ratio (see Section 4). Applied linearly to each merged PR. If your credibility is 0.80, every PR scores 80% of what it would at perfect credibility.
Review Quality Multiplier
| Maintainer Change Requests | Multiplier |
|---|---|
| 0 | 1.00 |
| 1 | 0.88 |
| 2 | 0.76 |
| 3 | 0.64 |
| 5 | 0.40 |
| 8 | 0.04 |
| 9+ | 0.00 |
Only counts CHANGES_REQUESTED reviews from maintainers (OWNER, MEMBER, COLLABORATOR). Regular contributor reviews don't affect this.
Spam Multiplier
Binary: 1.0 (normal) or 0.0 (all rewards zeroed).
| Your Total Token Score | Open PR Threshold |
|---|---|
| 0 - 299 | 10 |
| 300 - 599 | 11 |
| 600 - 899 | 12 |
| 3000+ | 20 |
| 6000+ | 30 (max) |
Issue Multiplier
If your PR closes a valid linked issue, you get a bonus multiplier between 1.0 and 2.0:
age_bonus = 0.75 × age_ratio
maintainer_bonus = 0.25 (if issue was created by a maintainer)
multiplier = 1.0 + age_bonus + maintainer_bonus
| Issue Age | Non-Maintainer Issue | Maintainer Issue |
|---|---|---|
| 1 day | 1.12 | 1.37 |
| 10 days | 1.38 | 1.63 |
| 20 days | 1.53 | 1.78 |
| 40+ days | 1.75 | 2.00 |
Rules for issue validity:
- The issue must have a different author than your PR (no self-created issues)
- The issue must have been created before your PR was created
- For merged PRs: the issue must be CLOSED within 1 day of merge
- The PR must not have been edited after it was merged
8. Bonus Systems
Pioneer Dividend
If you are the first miner to contribute a quality PR to any whitelisted repo, you become the pioneer for that repo.
When other miners (followers) later contribute to the same repo, you earn a cut of their scores:
| Follower Position | % of Their Earned Score You Get |
|---|---|
| 1st follower | 30% |
| 2nd follower | 20% |
| 3rd and beyond | 10% each |
Cap: The total pioneer dividend cannot exceed 1x your own earned_score on that repo. So at most, your score on that repo doubles.
Eligibility: A PR must be merged AND have token_score >= 5. Pioneer is determined by earliest merge date.
- Miner A earns 40 points → you get 40 × 0.30 = 12
- Miner B earns 30 points → you get 30 × 0.20 = 6
- Miner C earns 20 points → you get 20 × 0.10 = 2
- Total dividend: 20 points. Your total: 50 + 20 = 70 points
9. Penalties to Avoid
Open PR Collateral
Each open PR costs you 20% of its potential score, deducted from your total:
Even if you're under the spam threshold, open PRs actively hurt your score. Close or merge them.
Shared GitHub Account (Sybil Detection)
If the same GitHub user ID appears on multiple miner UIDs, ALL UIDs sharing that account get zeroed out. Not just the duplicates — everyone.
Maintainer PRs Are Filtered Out
If your GitHub account has OWNER, MEMBER, or COLLABORATOR status on a repo, your PRs to that repo are skipped entirely.
Self-Merged PRs
If the person who merged the PR is the same as the author AND there are no approving reviews from other people, the PR is skipped. You need at least one external approval.
10. Which Repos to Target
There are 1,414 whitelisted repositories across three tiers:
Tier Distribution
| Tier | Count | Weight Range | Description |
|---|---|---|---|
| Gold | 13 | 20.0 - 100.0 | Highest value. Bitcoin, Bittensor core, Entrius repos |
| Silver | 43 | 4.0 - 20.0 | High value. Major open-source projects |
| Bronze | 1,358 | 0.01 - 3.0 | Most repos. Median weight ~0.17 |
Top 20 Highest-Weight Repos
| Weight | Repository | Tier |
|---|---|---|
| 100.00 | bitcoin/bitcoin | Gold |
| 71.03 | opentensor/subtensor | Gold |
| 53.48 | entrius/allways | Gold |
| 53.48 | entrius/gittensor | Gold |
| 43.72 | latent-to/bittensor | Gold |
| 37.40 | bitcoin/bips | Gold |
| 32.92 | bitcoinj/bitcoinj | Gold |
| 29.55 | bitcoinjs/bitcoinjs-lib | Gold |
| 26.91 | entrius/allways-ui | Gold |
| 26.91 | entrius/gittensor-ui | Gold |
| 24.78 | latent-to/async-substrate-interface | Gold |
| 23.02 | latent-to/btwallet | Gold |
| 21.54 | latent-to/btcli | Gold |
| 20.00 | dbeaver/dbeaver | Silver |
| 20.00 | openclaw/openclaw | Silver |
| 17.36 | AffineFoundation/affine-cortex | Silver |
| 15.28 | AffineFoundation/affinetes | Silver |
| 13.72 | astral-sh/ruff | Silver |
| 12.49 | ethereum/go-ethereum | Silver |
| 11.50 | hoppscotch/hoppscotch | Silver |
- Realistic difficulty matters. bitcoin/bitcoin has the highest weight but extremely high review standards.
- Silver-tier repos often offer the best effort-to-reward ratio.
- Pioneer potential: If a high-weight repo has zero miner contributors, being first is very valuable.
- Your expertise matters. A strong PR to a lower-weight repo beats a rejected PR to a higher-weight one.
11. Which Languages Pay Most
Language weight is multiplied into your token score per file. Higher weight = more points per AST node.
| Weight | Languages |
|---|---|
| 2.0 | Rust (.rs), Go (.go), C (.c, .h), C++ (.cpp, .hpp), Haskell (.hs), CUDA (.cu) |
| 1.75 | Python (.py), Ruby (.rb), Java (.java), Kotlin (.kt), Lua (.lua), Clojure (.clj), OCaml (.ml), Shell (.sh, .zsh), Verilog, VHDL, D, PureScript, Scheme, Racket |
| 1.5 | TypeScript (.cts), Elixir, Erlang, Swift, SQL, Solidity, Svelte, Bash, Assembly, Pascal, GDScript, Gleam, GLSL, V, PowerShell, Fish, Nim |
| 1.0 - 1.25 | PHP, Vue, Astro, Prisma, JavaScript (.js = 1.05), TypeScript (.ts = 1.05, .tsx = 1.1), Dart, Julia, Scala, Zig, Nix, Terraform, YAML |
| 0.5 - 0.95 | CSS (0.95), SCSS (1.0), HTML (0.75), config files (0.5) |
| < 0.5 | Markdown (0.08), JSON (0.1), CSV (0.1), text (0.08), XML (0.2) |
12. PR Filtering Rules
Not every PR counts. The validator applies these filters:
PRs That Are Counted
- Merged to the default branch (usually
mainormaster) or explicitly listed additional acceptable branches - Merged within the last 35 days
- Author is NOT a maintainer (OWNER/MEMBER/COLLABORATOR) of the repo
- Not self-merged (unless there's an external approval)
- Repository is in the whitelist and not marked inactive
PRs That Are Skipped
| Condition | Result |
|---|---|
| Repo not in whitelist | Skipped entirely |
| Merged to non-default branch | Skipped |
| Author is repo maintainer | Skipped |
| Self-merged with no external approval | Skipped |
| Merged more than 35 days ago | Skipped (outside lookback) |
| Source branch is also an acceptable branch | Skipped |
| Created after repo's inactive date | Skipped |
Open PRs
- All open PRs to whitelisted repos are counted (no date filter)
- They contribute collateral deductions
- Too many open PRs triggers the spam penalty
Closed PRs
- Closed PRs within the 35-day window count toward credibility
- They don't earn any score themselves
- The mulligan forgives your first closed PR
13. Dynamic Emissions
After all miners are scored and normalized, the entire reward pool is scaled down based on overall network activity:
token_score_scalar = exponential_unlock(total_token_score_across_all_miners)
final_scalar = average(unique_repo_scalar, token_score_scalar)
| Metric | Max Recycle | Decay Rate | Meaning |
|---|---|---|---|
| Unique repos | 80% | 0.005 | More repos contributed to = less recycled |
| Token score | 80% | 0.000012 | Higher total scores = less recycled |
When the network has fewer miners or less activity, a larger portion of emissions gets recycled (sent to UID 0). As more miners contribute to more repos with higher quality, the scalar approaches 1.0.
14. Issue Bounties
Gittensor has a parallel reward system using smart contracts on Polkadot:
- 15% of total emissions go to an issue bounty treasury (UID 111)
- Repository maintainers can register issues with bounties
- When a miner's PR closes a registered bounty issue, they can earn the bounty
- Validators vote on solutions
gitt issues list # View registered bounty issues
gitt issues submissions <id> # View PR submissions for an issue
gitt harvest # Harvest pending bounty emissions
This is separate from the main OSS scoring system and is an additional earning opportunity.
15. Strategy Cheatsheet
Phase 1: Get Eligible (First Priority)
| Action | Why |
|---|---|
| Get 5 quality PRs merged to whitelisted repos | Meet the minimum merged PR requirement |
| Keep your closed PR count low | Stay above 75% credibility |
| Target PRs that will definitely be accepted | A rejected PR costs more than a delayed merge |
| Ensure each PR has token_score >= 5 | PRs below this threshold don't count as "valid" |
Phase 2: Maximize Score
| # | Action | Impact |
|---|---|---|
| 1 | Target high-weight repos (Gold/Silver tier) | Repo weight is the biggest score multiplier |
| 2 | Write structural code — functions, classes, interfaces | AST nodes score 2.0-2.5 vs 0.03-0.07 for literals |
| 3 | Use high-weight languages (Rust, Go, C, Python) | Up to 2x language multiplier |
| 4 | Fix old issues from maintainers | Up to 2x issue multiplier |
| 5 | Be first to contribute to untouched repos | Pioneer dividend can double your score |
| 6 | Submit clean code first time | Each change request costs 12% |
| 7 | Contribute steadily, not in bursts | Time decay halves value at 10 days |
| 8 | Keep open PRs under 10 | Exceeding threshold = all rewards zero |
| 9 | Close/merge open PRs promptly | Each open PR costs 20% collateral |
| 10 | Contribute to unique repos | Helps unlock network-level emissions |
Things to Avoid
| Don't | Why |
|---|---|
| Submit PRs you think will be rejected | Closed PRs destroy credibility |
| Pad PRs with comments | Comments score literally 0.0 |
| Make docs-only PRs | Markdown weight is 0.08 (nearly worthless) |
| Leave many PRs open | >10 open = all rewards zeroed |
| Use multiple GitHub accounts | Sybil detection zeros all linked UIDs |
| Try to self-merge | Self-merged without external approval = skipped |
| Contribute to repos where you're a maintainer | Maintainer PRs are filtered out |
| Rename variables for easy PRs | Identifiers score only 0.07 each |
| Submit huge generated/data files | >1MB files get zero score |
The Ideal PR
- Written in Rust, Go, or C (language weight 2.0)
- Merged to a Gold or Silver tier repo (weight 20+)
- Contains meaningful structural changes (new functions, classes, interfaces)
- Fixes an old issue created by a maintainer (up to 2x multiplier)
- Has dense, high-quality code (high token-score-to-lines ratio)
- Gets zero change-request reviews (clean first submission)
- Merged recently (within the last few days)
- Submitted to a repo where you're the first miner contributor (pioneer dividend)
Gittensor Miner Guide — Generated from source code analysis of Subnet 74 (v5.0.0)