Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d4815ff
improved error logging and file extension extraction (#312)
anderdc Mar 20, 2026
c790e93
add entrius/allways and entrius/allways-ui to master repositories (#317)
anderdc Mar 26, 2026
8e94f01
Remove `nushell/nushell` from whitelist (#316)
cptpiepmatz Mar 26, 2026
c70a24c
chore: add additional acceptable branches to traefik repos (#315)
Desel72 Mar 26, 2026
629cb66
fix: liveweb-arena weight (#320)
bittoby Mar 30, 2026
b920647
Remove `astral-sh/ruff` from whitelist (#322)
bittoby Mar 30, 2026
21b416c
address requested removals (#325)
anderdc Apr 1, 2026
8a74f90
fix: detect inline tests in languages like Rust, Zig, and D for accur…
bitloi Apr 1, 2026
08732e5
chore: update transferred GitHub repo names (#332)
it-education-md Apr 1, 2026
63582be
Update the agcli repo name which was moved to unarbos (#333)
bittoby Apr 2, 2026
087e6e2
Remove astropy/astropy (#334)
pllim Apr 2, 2026
d4ae0aa
address removals (#337)
anderdc Apr 2, 2026
ad759cd
fix: issues list --json --id returns null instead of structured error…
bitloi Apr 2, 2026
ec3a822
Revamp (#348)
anderdc Apr 7, 2026
9004ba9
fix: split GraphQL file content fetches into batches of 50 to prevent…
bittoby Apr 7, 2026
29d55a3
Deactivate autoppia repos (deregistered) (#347)
eureka0928 Apr 7, 2026
04f1300
Improve CLI help output and shared option decorators (#341)
it-education-md Apr 7, 2026
ae64b04
fix: use merge-base for tree-diff scoring to avoid inflated token sco…
MkDev11 Apr 7, 2026
02efe48
chore(weights): sync subnet identity repos
ventura-oss Apr 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ data/
logs/
*.log

# Documentation (not needed in container, except README.md for setup.py)
# Documentation (not needed in container)
docs/

# Tests (not needed in production)
Expand Down
7 changes: 1 addition & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,11 @@ HOTKEY_NAME=default
# Weights & Biases API key for logging
# Signup https://wandb.ai/site for a key
WANDB_API_KEY=
# for issue bounties api calls
# GitHub PAT for validator API calls
GITTENSOR_VALIDATOR_PAT=
# Optional custom name for wandb logging
WANDB_VALIDATOR_NAME=vali

# ******* MINER VARIABLES *******
# GitHub Personal Access Token
# https://github.com/settings/personal-access-tokens
GITTENSOR_MINER_PAT=

# validator database settings (for gittensor validator/dashboard)
STORE_DB_RESULTS=false
# DB_HOST=
Expand Down
26 changes: 13 additions & 13 deletions .github/PULL_REQUEST_TEMPLATE/weight_adjustment.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@

### Changes Summary

| Metric | Gold | Silver | Bronze | Total |
| -------------------- | ---- | ------ | ------ | ----- |
| Repositories Added | 0 | 0 | 0 | 0 |
| Repositories Removed | 0 | 0 | 0 | 0 |
| Weights Modified | 0 | 0 | 0 | 0 |
| Net Weight Change | 0 | 0 | 0 | 0 |
| Metric | Total |
| -------------------- | ----- |
| Repositories Added | 0 |
| Repositories Removed | 0 |
| Weights Modified | 0 |
| Net Weight Change | 0 |

### Added Repositories

<!-- Delete this section if none -->

| Repository | Tier | Branch | Weight |
| ---------- | ------ | ------ | ------ |
| owner/repo | silver | main | 20.00 |
| Repository | Branch | Weight |
| ---------- | ------ | ------ |
| owner/repo | main | 20.00 |

### Removed Repositories

<!-- Delete this section if none -->

| Repository | Tier | Reason |
| ---------- | ------ | ------ |
| owner/repo | silver | — |
| Repository | Reason |
| ---------- | ------ |
| owner/repo | — |

### Justification

Expand All @@ -49,4 +49,4 @@ Example:

- [ ] Changes summary table is filled in accurately
- [ ] Net weight changes are justified in the Justification section
- [ ] Added repositories have correct tier, branch, and initial weight
- [ ] Added repositories have correct branch and initial weight
14 changes: 6 additions & 8 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
run: uv python install 3.12

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
run: uv sync --extra dev

- name: Run tests
run: pytest tests/ -v
run: uv run pytest tests/ -v
23 changes: 23 additions & 0 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Type Check

on:
pull_request:
branches: [main, test]

jobs:
pyright:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Set up Python
run: uv python install 3.12

- name: Install dependencies
run: uv sync --extra dev

- name: Run pyright
run: uv run pyright
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ wandb

*.log

# Merge predictions local DB
merge-prediction-data/
gt-merge-preds.db
gt-merge-preds.db-wal
gt-merge-preds.db-shm
# Validator data directory (contains sensitive miner PATs)
data/

CLAUDE.md
.claude/
Expand All @@ -30,3 +27,6 @@ CLAUDE.md
target/
**/*.rs.bk
*.lock
!uv.lock

**/.venv/
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,22 @@ The result: a sustainable incentive layer that channels resources toward buildin

## Miners

**Recommended: Deploy with Docker**

> [!NOTE]
> The port in .env must be accessible by the public.
No miner neuron required — just register your GitHub PAT with validators using the CLI.

```bash
# Quick start
# Install
git clone https://github.com/entrius/gittensor.git
cd gittensor
cp .env.example .env
# Edit .env with proper values
nano .env
uv sync

# Set your GitHub PAT
export GITTENSOR_MINER_PAT=ghp_your_token_here

# Broadcast PAT to validators
gitt miner post --wallet <name> --hotkey <hotkey>

docker-compose -f docker-compose.miner.yml up -d
# Check which validators have your PAT stored
gitt miner check --wallet <name> --hotkey <hotkey>
```

See full guide **[here](https://docs.gittensor.io/miner.html)**
Expand Down
15 changes: 0 additions & 15 deletions docker-compose.miner.yml

This file was deleted.

2 changes: 1 addition & 1 deletion docker-compose.vali.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ services:
volumes:
# 'ro' = readonly
- ${WALLET_PATH}:/root/.bittensor/wallets:ro
- ./merge-prediction-data:/app/data
- ./data:/app/data
# optional: uncomment this if you are running validator database
# networks:
# - gittensor_network
Expand Down
41 changes: 12 additions & 29 deletions gittensor/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from gittensor.constants import MIN_TOKEN_SCORE_FOR_BASE_SCORE
from gittensor.utils.utils import parse_repo_name
from gittensor.validator.oss_contributions.tier_config import Tier, TierConfig, TierStats

GITHUB_DOMAIN = 'https://github.com/'

Expand Down Expand Up @@ -73,7 +72,8 @@ def __post_init__(self):
self.file_extension = self._calculate_file_extension()

def _calculate_file_extension(self) -> str:
return self.filename.split('.')[-1].lower() if '.' in self.filename else ''
basename = self.filename.split('/')[-1]
return basename.split('.')[-1].lower() if '.' in basename else ''

def is_test_file(self) -> bool:
filename_lower = self.filename.lower()
Expand Down Expand Up @@ -142,15 +142,14 @@ class PullRequest:
repository_full_name: str
uid: int
hotkey: str
github_id: str
github_id: Optional[str]
title: str
author_login: str
merged_at: Optional[datetime] # None for OPEN PRs
created_at: datetime

# PR state based fields
pr_state: PRState
repository_tier_configuration: Optional[TierConfig] = None # assigned when scoring PR

# Score fields
repo_weight_multiplier: float = 1.0
Expand All @@ -163,8 +162,6 @@ class PullRequest:
credibility_multiplier: float = 1.0
review_quality_multiplier: float = 1.0 # Penalty for CHANGES_REQUESTED reviews from maintainers
changes_requested_count: int = 0 # Number of maintainer CHANGES_REQUESTED reviews
raw_credibility: float = 1.0 # Before applying ^k scalar
credibility_scalar: int = 1 # The k value from tier config
earned_score: float = 0.0
collateral_score: float = 0.0 # For OPEN PRs: potential_score * collateral_percent

Expand Down Expand Up @@ -195,14 +192,9 @@ def set_file_changes(self, file_changes: List[FileChange]) -> None:
def is_pioneer_eligible(self) -> bool:
"""Check if this PR qualifies for pioneer consideration.

A PR is eligible if it is merged, has a tier configuration,
and meets the minimum token score quality gate.
A PR is eligible if it is merged and meets the minimum token score quality gate.
"""
return (
self.repository_tier_configuration is not None
and self.merged_at is not None
and self.token_score >= MIN_TOKEN_SCORE_FOR_BASE_SCORE
)
return self.merged_at is not None and self.token_score >= MIN_TOKEN_SCORE_FOR_BASE_SCORE

def calculate_final_earned_score(self) -> float:
"""Combine base score with all multipliers. Pioneer dividend is added separately after."""
Expand All @@ -217,13 +209,7 @@ def calculate_final_earned_score(self) -> float:

self.earned_score = self.base_score * prod(multipliers.values())

# Log all multipliers (credibility shows ^k format)
def _format_multiplier(k: str, v: float) -> str:
if k == 'cred':
return f'cred={self.raw_credibility:.2f}^{self.credibility_scalar}'
return f'{k}={v:.2f}'

mult_str = ' × '.join(_format_multiplier(k, v) for k, v in multipliers.items())
mult_str = ' × '.join(f'{k}={v:.2f}' for k, v in multipliers.items())
bt.logging.info(
f'├─ {self.pr_state.value} PR #{self.number} ({self.repository_full_name}) → {self.earned_score:.2f}'
)
Expand All @@ -232,7 +218,7 @@ def _format_multiplier(k: str, v: float) -> str:
return self.earned_score

@classmethod
def from_graphql_response(cls, pr_data: dict, uid: int, hotkey: str, github_id: str) -> 'PullRequest':
def from_graphql_response(cls, pr_data: dict, uid: int, hotkey: str, github_id: Optional[str]) -> 'PullRequest':
"""Create PullRequest from GraphQL API response for any PR state."""
from gittensor.validator.utils.datetime_utils import parse_github_timestamp_to_cst

Expand Down Expand Up @@ -261,9 +247,8 @@ def from_graphql_response(cls, pr_data: dict, uid: int, hotkey: str, github_id:
)

description: str = pr_data.get('bodyText', '')
last_edited_at = (
parse_github_timestamp_to_cst(pr_data.get('lastEditedAt')) if pr_data.get('lastEditedAt') else None
)
raw_edited_at = pr_data.get('lastEditedAt')
last_edited_at = parse_github_timestamp_to_cst(raw_edited_at) if isinstance(raw_edited_at, str) else None
merged_at = parse_github_timestamp_to_cst(pr_data['mergedAt']) if is_merged else None

return cls(
Expand Down Expand Up @@ -300,7 +285,6 @@ class MinerEvaluation:
total_collateral_score: float = 0.0 # Collateral from open PRs
total_nodes_scored: int = 0 # Total AST nodes scored across all PRs
unique_repos_count: int = 0
qualified_unique_repos_count: int = 0 # Repos meeting min token score threshold

# Overall token scoring breakdown (aggregated across all PRs)
total_token_score: float = 0.0
Expand All @@ -315,10 +299,9 @@ class MinerEvaluation:
closed_pull_requests: List[PullRequest] = field(default_factory=list)
unique_repos_contributed_to: Set[str] = field(default_factory=set)

# Tier level details (None = no tier unlocked yet)
current_tier: Optional[Tier] = None
credibility_by_tier: Dict[Tier, float] = field(default_factory=dict)
stats_by_tier: Dict[Tier, TierStats] = field(default_factory=lambda: {tier: TierStats() for tier in Tier})
# Eligibility and credibility
is_eligible: bool = False
credibility: float = 0.0

@property
def total_prs(self) -> int:
Expand Down
19 changes: 3 additions & 16 deletions gittensor/cli/issue_commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
gitt issues (alias: i) - Issue management commands
list List issues or view a specific issue
submissions List open PR submissions for an issue
predict Predict merge probabilities for PR submissions
register Register a new issue bounty
bounty-pool View total bounty pool
pending-harvest View pending emissions
Expand All @@ -25,6 +24,7 @@
import click

from .admin import admin
from .help import StyledGroup

# Re-export helpers
from .helpers import (
Expand All @@ -41,31 +41,19 @@
issue_harvest,
issue_register,
)
from .predict import issues_predict
from .submissions import issues_submissions
from .view import admin_info, issues_bounty_pool, issues_list, issues_pending_harvest
from .vote import vote


@click.group(name='issues')
@click.group(name='issues', cls=StyledGroup)
def issues_group():
"""Issue management commands.

\b
Commands:
list List issues or view a specific issue
submissions List open PR submissions for an issue
predict Predict merge probabilities for PR submissions
register Register a new issue bounty
bounty-pool View total bounty pool
pending-harvest View pending emissions
"""
"""Manage issue bounties, submissions, and predictions."""
pass


issues_group.add_command(issues_list, name='list')
issues_group.add_command(issues_submissions, name='submissions')
issues_group.add_command(issues_predict, name='predict')
issues_group.add_command(issue_register, name='register')
issues_group.add_command(issues_bounty_pool, name='bounty-pool')
issues_group.add_command(issues_pending_harvest, name='pending-harvest')
Expand Down Expand Up @@ -97,7 +85,6 @@ def register_commands(cli):
'vote',
'admin',
'issues_submissions',
'issues_predict',
'issue_register',
'issue_harvest',
# Helpers
Expand Down
Loading