Architecture#
Overview#
Gittensory is an npm monorepo-based platform for managing GitHub issues with bounties, contributor scoring, and AI agent integration in the context of the Gittensor ecosystem. It ingests data from GitHub and the Gittensor registry, applies multi-signal intelligence algorithms to evaluate contributor work, and exposes that intelligence across three surfaces: a REST API (served from Cloudflare Workers), a Model Context Protocol (MCP) server (for AI coding agents), and a GitHub App (for comments, labels, and check runs).
The system is designed around a few core principles:
- Privacy by default — source code never leaves the developer's machine; only metadata is transmitted to the backend
- Serverless edge deployment — the entire backend runs on Cloudflare Workers for global low-latency access
- Queue-driven architecture — all heavy computation is decoupled into background jobs processed asynchronously
- Full type safety — TypeScript end-to-end, from the database schema through Drizzle ORM to the API layer and frontend
The monorepo contains four main workspaces: the core /src backend, a React frontend at /apps/gittensory-ui, a browser extension at /apps/gittensory-extension, and the published MCP CLI package at /packages/gittensory-mcp .
Monorepo Structure#
Gittensory uses an npm workspaces-based monorepo organized into distinct functional areas . The repository structure separates core backend logic in /src, frontend and extension applications in /apps, and reusable packages in /packages.
Top-Level Organization#
gittensory/
├── .github/ # GitHub Actions workflows
├── apps/ # Application workspaces
│ ├── gittensory-ui/ # Web interface
│ └── gittensory-extension/ # Browser extension
├── migrations/ # Database migration files
├── packages/ # Shared packages
│ └── gittensory-mcp/ # MCP CLI wrapper
├── scripts/ # Build and maintenance scripts
├── src/ # Core API backend
├── test/ # Test suites
├── drizzle.config.ts # Database ORM configuration
├── tsconfig.json # TypeScript configuration
├── vitest.config.ts # Primary test configuration
├── vitest.workers.config.ts # Workers-specific test config
├── wrangler.jsonc # Cloudflare Workers configuration
├── wrangler.vitest.jsonc # Workers test environment config
├── package.json # Root workspace manifest
├── .nvmrc # Node.js version pinning
├── renovate.json # Dependency update automation
├── cliff.toml # Root changelog configuration
├── cliff.mcp.toml # MCP package changelog config
└── worker-configuration.d.ts # Cloudflare type definitions
The repository uses npm 10.9.2 as the package manager with Node.js ≥22.0.0 required . Workspaces are configured for apps/* and packages/* directories .
/src — Core API Backend#
The /src directory contains the main Cloudflare Workers-based API backend . It is organized into 15 functional modules:
api/— HTTP route definitions and middlewareauth/— Authentication and authorization logicbounties/— Bounty data normalizationdb/— Database client, schema, and repositoriesgithub/— GitHub API integration and webhooksgittensor/— Gittensor protocol integrationmcp/— Model Context Protocol server implementationopenapi/— OpenAPI specification generationqueue/— Job queue processing and schedulingregistry/— Registry snapshot managementrules/— Advisory rules enginescoring/— Scoring model synchronizationservices/— Cross-cutting service layerssignals/— Intelligence signal generationupstream/— Upstream source tracking and drift detectionutils/— Shared utilities
The entry point is src/index.ts, which exports three Cloudflare Workers handlers :
fetch— HTTP request handler for the APIqueue— Processes job messages from thegittensory-jobsqueuescheduled— Executes cron-triggered jobs every 30 minutes
Additional key files include src/types.ts, which defines comprehensive TypeScript types for the entire system , and src/queue-intelligence.ts for advanced queue orchestration .
/apps/gittensory-ui — Frontend#
The frontend application lives in apps/gittensory-ui and uses TanStack Start v1.167, a React-based full-stack framework . The stack includes:
- React 19.2.0 for UI components
- TanStack Router v1.168 for type-safe routing
- TanStack React Query v5.83 for server state management
- Radix UI headless component primitives (accordion, dialog, dropdown, hover card, popover, select, tabs, tooltip, and more)
- Tailwind CSS v4 for styling
- React Hook Form + Zod for form validation
- Recharts for data visualization
- Vite as the build tool
The application is deployed to https://gittensory.aethereal.dev/.
/apps/gittensory-extension — Browser Extension#
The browser extension is a Chrome Manifest V3 extension named "Gittensory Maintainer Overlay" . It provides private Gittensory pull request context directly on GitHub .
Architecture:
- Service worker background process
- Content script using ES6 modules (
"type": "module"), injected on GitHub PR pages (https://github.com/*/*/pull/*) and issue pages (https://github.com/*/*/issues/*) - Host permissions for
github.comandgittensory-api.aethereal.dev
The extension is implemented in plain JavaScript with no build step, version 0.1.0 .
Core modules:
- github-target.js — Parses GitHub PR and issue URLs via
parseGitHubPageTarget(), returning structured targets withkind,owner,repo, andpullNumberorissueNumber. IncludesisSupportedGitHubOverlayPath()to validate pathnames. - overlay-safety.js — Enforces security and safety boundaries.
EXTENSION_SOURCE_UPLOAD_ENABLED = falseensures the extension never uploads source code.isOverlayDisplaySafe()andredactForOverlayDisplay()prevent display of sensitive maintainer-only terms (wallet, hotkey, coldkey, mnemonic, private paths).escapeOverlayHtml()prevents XSS attacks.renderOverlayPanels()combines sanitization and rendering for overlay panel markup. - content.js — Detects page type, mounts PR overlays for pull requests, and displays scaffold notices for issue pages. Issue pages show a notice that Gittensory context is available on the linked PR.
/packages/gittensory-mcp — MCP CLI Package#
The gittensory-mcp package is a local stdio MCP (Model Context Protocol) wrapper for the Gittensory base-agent . Published as @jsonbored/gittensory-mcp on npm, it provides a CLI binary named gittensory-mcp .
Dependencies:
@modelcontextprotocol/sdkv1.26.0zodfor validation
Requirements:
- Node.js ≥22.0.0
- AGPL-3.0-only license
Backend Stack#
Gittensory's backend operates on Cloudflare Workers, a serverless edge runtime that distributes request handling globally. The system uses Hono as its web framework, SQLite via Cloudflare D1 for persistence, and Drizzle ORM for type-safe database operations.
Runtime: Cloudflare Workers#
The backend runs as a Cloudflare Worker named gittensory-api , configured with compatibility date 2026-05-28 and the nodejs_compat flag . The nodejs_compat flag enables Node.js APIs in the Workers runtime, allowing the use of standard Node.js modules and patterns within the edge environment.
Smart placement mode provides automatic global edge routing , ensuring requests are handled by the geographically nearest Worker instance. Full observability is enabled with 100% head sampling for both logs and traces , providing complete visibility into production behavior.
Bindings and Resources#
The Worker integrates with several Cloudflare services through bindings:
- D1 Database: Binding
DBconnects to thegittensorydatabase, with migrations stored in the./migrationsdirectory - Durable Objects: Binding
RATE_LIMITERprovides access to theRateLimiterclass for distributed rate limiting - Queues: Producer binding
JOBSallows enqueueing work to thegittensory-jobsqueue - Queue Consumer: Processes messages from
gittensory-jobswith a maximum batch size of 10 and 5-second timeout - AI: Binding
AIenables access to Cloudflare Workers AI
Cron triggers fire every 30 minutes (*/30 * * * *) to schedule periodic jobs .
Three-Handler Pattern#
The Worker exports three distinct handlers :
-
fetch— HTTP request handler that delegates toapp.fetchfrom the Hono router . This handles all incoming HTTP requests to the API. -
queue— Processes job message batches from thegittensory-jobsqueue . Each message is processed viaprocessJob(), acknowledged on success, or retried on failure. -
scheduled— Triggered by cron, enqueues jobs based on time intervals :- Every minute:
backfill-registered-repos,repair-data-fidelity,refresh-installation-health - Every hour (minute 0):
refresh-registry,refresh-scoring-model,refresh-upstream-drift,rollup-product-usage - Every 6 hours (minute 0, hour % 6 == 0):
generate-signal-snapshots,build-burden-forecasts,build-contributor-evidence,build-contributor-decision-packs,file-upstream-drift-issues
- Every minute:
This pattern separates HTTP handling, asynchronous job processing, and scheduled task execution into distinct responsibilities.
Web Framework: Hono#
Hono (version ^4.12.23) serves as the web framework . Hono is a lightweight, ultrafast framework designed for edge runtimes, integrating natively with Cloudflare Workers' fetch handler. It provides routing, middleware, and context handling with minimal overhead.
The application is created via createApp() from src/api/routes.ts and exposed through the fetch export . All HTTP routes are defined in src/api/routes.ts, which constructs a Hono instance and attaches route handlers for all API endpoints.
Database: SQLite via Cloudflare D1#
Cloudflare D1 provides a distributed SQLite database accessible at the edge. The Drizzle configuration specifies sqlite dialect with d1-http driver , enabling type-safe queries against the D1 database.
The database client is initialized through getDb() in src/db/client.ts, which wraps the D1 database binding with Drizzle's ORM layer and the application schema. This provides type-safe database access throughout the backend.
Database migrations are stored in ./migrations and applied via Wrangler commands: db:migrate:local for local development and db:migrate:remote for production .
ORM: Drizzle ORM#
Drizzle ORM (version ^0.45.0) provides type-safe query building . The schema is defined in src/db/schema.ts, and drizzle-kit (^0.31.7) generates migrations via the drizzle:generate command .
The repository pattern is implemented in src/db/repositories.ts, containing over 1700 lines of database access functions that abstract query logic and provide a clean interface for data operations throughout the application.
Key Dependencies#
Core backend dependencies include :
- @modelcontextprotocol/sdk (1.26.0): MCP server implementation
- @octokit/core (^7.0.6): GitHub API client
- agents (^0.7.9): AI agent orchestration
- zod (^3.25.76): Runtime type validation
- @asteasolutions/zod-to-openapi (^7.3.4): OpenAPI spec generation from Zod schemas
Development Tooling#
TypeScript ^5.9.3 provides static typing , with a minimum Node.js version of 22.0.0 required . Wrangler ^4.95.0 handles deployment and local development via wrangler dev .
Frontend Stack#
The Gittensory web interface is a full-stack React application located at /apps/gittensory-ui and deployed to https://gittensory.aethereal.dev/.
Framework#
The UI is built on the TanStack ecosystem :
- TanStack Start (v1.167) — A React-based full-stack framework that provides server-side rendering (SSR) capabilities, file-based routing, and seamless data loading patterns.
- TanStack Router (v1.168) — Type-safe client-side routing with first-class support for search params, nested layouts, and route loaders.
- TanStack Query (v5.83) — Async state management for data fetching, caching, and background synchronisation.
React 19.2.0 is used as the underlying view layer, with Vite as the build tool .
Styling & Components#
| Library | Version | Role |
|---|---|---|
| Tailwind CSS | v4.2.1 | Utility-first CSS framework for all styling |
| Radix UI | Various | Headless, accessible component primitives |
| class-variance-authority | — | Variant-based component class composition |
| clsx / tailwind-merge | — | Conditional className utilities |
Radix UI provides unstyled, accessible building blocks (accordion, alert dialog, avatar, checkbox, dialog, dropdown menu, and more) which are styled using Tailwind CSS. This pattern keeps accessibility semantics correct while giving full visual control.
Additional Libraries#
- React Hook Form + Zod — Type-safe form state management and validation
- Recharts — Declarative SVG charting for analytics dashboards
- Sonner — Toast notifications
- Motion — Animation library for UI transitions
OpenAPI Integration#
The UI build pipeline includes an OpenAPI generation step (ui:openapi) that produces a typed API client from the backend's /openapi.json endpoint. The ui:openapi:check script validates that the generated spec stays in sync with the actual route definitions .
Data Layer#
Gittensory uses Cloudflare D1 (SQLite) as its database, managed through Drizzle ORM for type-safe data access and schema migrations.
Database Configuration#
The database is configured via Drizzle Kit with SQLite dialect and D1 HTTP driver :
- Dialect: sqlite
- Driver: d1-http
- Schema:
src/db/schema.ts - Migrations:
./migrations
Schema Organization#
The schema defines 45 tables organized by functional domain :
Installation & Repository Management#
- installations — GitHub app installations with permissions and webhook events (src/db/schema.ts)
- repositories — Repository metadata, installation status, registration status, and registry configuration (src/db/schema.ts)
- repositorySettings — Per-repository configuration for comment mode, check runs, labels, and public surface (src/db/schema.ts)
- repoSyncState — Repository-level sync status tracking with segment timestamps (src/db/schema.ts)
- repoSyncSegments — Paginated sync segments for labels, issues, PRs, and merged PRs (src/db/schema.ts)
- repoLabels — GitHub labels with configuration flags and observation counts (src/db/schema.ts)
PRs & Issues#
- pullRequests — Core PR data with labels, linked issues, and author association (src/db/schema.ts)
- pullRequestFiles — Files changed in each PR with addition/deletion counts (src/db/schema.ts)
- pullRequestReviews — PR review data with reviewer login and state (src/db/schema.ts)
- pullRequestDetailSyncState — Sync status for PR files, reviews, and checks (src/db/schema.ts)
- recentMergedPullRequests — Denormalized recent merged PRs with changed files (src/db/schema.ts)
- issues — Issue tracking with labels and linked PRs (src/db/schema.ts)
- issueQualityReports — Quality assessments for issues (src/db/schema.ts)
Contributors#
- contributors — Contributor profiles from GitHub with top languages (src/db/schema.ts)
- contributorRepoStats — Per-repository activity metrics: PRs, merges, issues, dominant labels (src/db/schema.ts)
- contributorEvidence — Evidence data for scoring decisions (src/db/schema.ts)
- contributorScoringProfiles — Scoring model outputs per contributor (src/db/schema.ts)
Check Runs & Advisories#
- checkSummaries — Check run summaries by SHA with status and conclusion (src/db/schema.ts)
- advisories — Quality advisories with findings and severity levels (src/db/schema.ts)
Snapshot / Data Warehouse#
- repoGithubTotalsSnapshots — GitHub totals for issues, PRs, and labels (src/db/schema.ts)
- repoSnapshots — Repository snapshots with counts and language data (src/db/schema.ts)
- registrySnapshots — Registry emission shares and repo counts (src/db/schema.ts)
- scoringModelSnapshots — Scoring constants and programming language weights (src/db/schema.ts)
- scorePreviews — Score preview results for PRs and issues (src/db/schema.ts)
- signalSnapshots — Multi-dimensional analysis snapshots by signal type (src/db/schema.ts)
- upstreamSourceSnapshots — Upstream source file snapshots with commit and blob SHA (src/db/schema.ts)
- upstreamRulesetSnapshots — Upstream ruleset snapshots with semantic hash (src/db/schema.ts)
- upstreamDriftReports — Drift detection reports with severity and affected areas (src/db/schema.ts)
Bounties#
- bounties — Bounty tracking with status, amount, and source URL (src/db/schema.ts)
- bountyLifecycleEvents — Lifecycle event log for bounties (src/db/schema.ts)
Agent & Operations#
- agentRuns — Agent orchestration runs with objective and status (src/db/schema.ts)
- agentActions — Agent action recommendations with risk impact (src/db/schema.ts)
- agentContextSnapshots — Agent context with decision pack and signal snapshot IDs (src/db/schema.ts)
- githubAgentCommandAnswers — Stores command invocations and responses from the GitHub agent (@gittensory), including repo, issue number, command name, request/response comment IDs, actor kind, and metadata. Indexed by (repo_full_name, issue_number) and (command, updated_at).
- githubAgentCommandFeedback — Records usefulness votes (thumbs-up/thumbs-down reactions) on command answers, with unique constraint on (answer_id, actor_hash) to deduplicate feedback per actor. Tracks vote, source (reaction or app feedback), actor kind, and links to github_agent_command_answers via foreign key. Indexed by (answer_id, actor_hash), (command, updated_at), and (repo_full_name, issue_number).
- syncRuns — Sync job execution tracking (src/db/schema.ts)
- webhookEvents — GitHub webhook delivery tracking with payload hash (src/db/schema.ts)
Auth & Usage#
- authSessions — User auth sessions with token hash and scopes (src/db/schema.ts)
- digestSubscriptions — Email digest subscriptions (src/db/schema.ts)
- auditEvents — Audit trail for security-relevant actions (src/db/schema.ts)
- productUsageEvents — Product usage telemetry with redacted actor hashes (src/db/schema.ts)
- productUsageDailyRollups — Daily usage rollups with activation funnels (src/db/schema.ts)
- aiUsageEvents — AI feature usage tracking with estimated neuron costs (src/db/schema.ts)
Health#
- installationHealth — Installation health status with permission checks (src/db/schema.ts)
- githubRateLimitObservations — GitHub rate limit tracking by resource and path (src/db/schema.ts)
- officialMinerDetections — Cached Gittensor miner detection results (src/db/schema.ts)
- collisionEdges — Collision detection edges between PRs and issues (src/db/schema.ts)
- burdenForecasts — Maintainer burden forecasts per repository (src/db/schema.ts)
- registryDriftEvents — Registry change event log (src/db/schema.ts)
Schema Patterns#
The schema uses consistent patterns for data integrity and performance :
- JSON columns for flexible payloads:
payloadJson,labelsJson,linkedIssuesJson(src/db/schema.ts) - Unique indexes on composite keys for data integrity (e.g.,
repo_full_name + number) (src/db/schema.ts) - Regular indexes on query hot paths: timestamps, status fields, login fields (src/db/schema.ts)
- Boolean storage as SQLite integer with
mode: "boolean"(src/db/schema.ts) - ISO timestamps as text with
CURRENT_TIMESTAMPdefaults (src/db/schema.ts)
ORM & Access Layer#
Data access is managed through Drizzle ORM with a repository pattern :
- Drizzle ORM: ^0.45.0 for type-safe queries
- Client:
src/db/client.tsprovidesgetDb()to initialize Drizzle with D1 binding - Repository pattern:
src/db/repositories.tsimplements 1700+ lines of type-safe data access functions - drizzle-kit: ^0.31.7 for schema and migration management
Migration Scripts#
Migration workflows are managed through npm scripts :
drizzle:generate— Generate migrations from schema changesdb:migrate:local— Apply migrations to local D1db:migrate:remote— Apply migrations to remote D1
All schema definitions flow through TypeScript types from table definitions to API responses, ensuring full type safety across the stack.
Key Backend Modules#
The backend intelligence of Gittensory is organized into nine major modules, each handling a distinct domain of the system's functionality. These modules operate as the core orchestration layer between GitHub data, Gittensor registry state, and Gittensory's signals intelligence.
Scoring Module (src/scoring/)#
The scoring module fetches and normalizes scoring constants from the upstream Gittensor repository to ensure Gittensory's score previews remain aligned with the official validator scoring implementation (model.ts).
The refreshScoringModelSnapshot() function fetches the latest scoring constants and programming language weights from GitHub (src/scoring/model.ts). It probes the upstream Gittensor repository at https://raw.githubusercontent.com/entrius/gittensor/test/gittensor/constants.py for scoring constants and a separate JSON file for programming language weights (src/scoring/model.ts). When the upstream source is unreachable, the module falls back to default constants defined locally (src/scoring/model.ts).
The parsePythonNumberConstants() function parses Python constant definitions using a regex pattern to extract uppercase variable names and their numeric values (src/scoring/model.ts). By default, it filters to a known set of constant names to prevent ingesting unrelated Python variables.
The detectActiveModel() function distinguishes between scoring model generations by checking for the presence of specific constant names (src/scoring/model.ts). It identifies saturation-based models by the presence of SRC_TOK_SATURATION_SCALE and density-based models by the presence of both MAX_CODE_DENSITY_MULTIPLIER and MIN_TOKEN_SCORE_FOR_BASE_SCORE (src/scoring/model.ts). This detection enables Gittensory to adapt its score preview logic to match whichever model the upstream validators are actively using.
Snapshots are persisted to the scoringModelSnapshots table and include the source kind (raw-github, api, or fallback), active model classification, constants, programming language weights, and any warnings encountered during fetch or parse (src/scoring/model.ts).
Queue Module (src/queue/)#
The queue module is the central async job orchestrator, routing all background work through a single switch statement (processors.ts).
The processJob() function dispatches on 20+ job message types (src/queue/processors.ts), including refresh-registry, backfill-registered-repos, generate-signal-snapshots, refresh-scoring-model, refresh-upstream-drift, build-contributor-evidence, build-burden-forecasts, repair-data-fidelity, rollup-product-usage, run-agent, and github-webhook (src/types.ts). Each job type is handled by a dedicated function that performs the work and updates the database.
Jobs are produced by the Cloudflare Workers scheduled handler, which runs every 30 minutes (wrangler.jsonc). Different jobs execute at different intervals: every minute for backfill and health checks, every hour (at minute 0) for registry and scoring model refresh, and every 6 hours (at 0, 6, 12, 18 UTC) for signal snapshot generation and burden forecasts (src/index.ts).
The queue is configured as a Cloudflare Queue named gittensory-jobs with a batch size of 10 messages and a 5-second timeout (wrangler.jsonc). Failed jobs are retried automatically by the queue infrastructure, and the module includes structured JSON logging with message IDs for observability.
When processing github-webhook jobs, the queue module upserts installations, repositories, and pull requests or issues from the webhook payload, then builds and persists advisory findings and optionally publishes public surfaces (comments, labels, check runs) depending on repository settings (src/queue/processors.ts).
Signals Module (src/signals/)#
The signals module is the core intelligence layer, building comprehensive multi-dimensional analysis from cached GitHub metadata (engine.ts, 3260 lines).
It constructs collision reports to detect duplicate or overlapping work by comparing titles, linked issues, and changed files across open issues, open pull requests, and recently merged pull requests (src/signals/engine.ts). The buildCollisionReport() function uses term overlap heuristics to identify pairs of items that share meaningful keywords or reference the same linked issue.
Queue health assessments are generated by buildQueueHealth(), which computes a burden score from the number of open pull requests, open issues, unlinked PRs, stale PRs, and collision clusters (src/signals/engine.ts). The burden score is clamped to 0-100 and mapped to a level (low, medium, high, critical) to provide a simple signal for maintainers.
Contributor profiles are built by buildContributorProfile(), which aggregates data from the Gittensor API (if available), cached pull requests and issues, and repo stats (src/signals/engine.ts). The profile includes trust signals such as evidence score, unlinked open pull requests, and maintainer-associated activity, as well as a breakdown of registered-repo activity by repository.
Preflight results are generated by buildPreflightResult(), which evaluates a planned PR for lane correctness, linked issue presence, duplicate risk, and test evidence (src/signals/engine.ts). The result includes findings with severity levels and a status (ready, needs_work, hold) to guide contributors before they open a PR.
Signals are consumed in three ways: (1) persisted to the signalSnapshots table for historical tracking, (2) returned via MCP tools for AI agents, and (3) included in GitHub comments and check runs for public visibility.
Registry Module (src/registry/)#
The registry module syncs the Gittensor registry from multiple API candidates with graceful fallback (sync.ts).
The refreshRegistry() function probes a list of API endpoints in order, starting with official Gittensor API URLs and falling back to a raw GitHub URL (src/registry/sync.ts, src/registry/sync.ts). For each candidate, it fetches the JSON payload, normalizes it using normalizeRegistryPayload(), and persists the snapshot to the registrySnapshots table. If any probe succeeds, the function returns immediately; if all fail, it throws an error.
The normalization step extracts which repositories are registered, their emission shares, issue-discovery shares, label multipliers, maintainer cuts, and other configuration fields. The snapshot also records the source kind (api or raw-github), the source URL, and any warnings encountered during fetch or parse.
After persisting the snapshot, the module updates the repositories table to mark repos as registered or unregistered, sets their emission shares and label multipliers, and clears registration state for repos that are no longer in the registry (src/registry/sync.ts).
The getLatestRegistrySnapshot() function retrieves the most recent snapshot for use in scoring previews and lane advice (src/registry/sync.ts).
Bounties Module (src/bounties/)#
The bounties module normalizes bounty data from Gitt, Gittensor's external bounty service (ingest.ts).
The normalizeGittBountySnapshot() function accepts a raw Gitt issue list payload and maps each issue to a standardized BountyRecord (src/bounties/ingest.ts). The record includes the bounty ID, repository full name, issue number, status, amount text (if available), a source URL, and a payload containing the original Gitt data.
Bounties are stored in the bounties table, and lifecycle events (such as status changes) are tracked in the bountyLifecycleEvents table. The module does not manage the lifecycle itself; it only ingests and normalizes the data for use in signals and advisories.
The signals module uses bounty data to classify bounty lifecycle states (active, historical, completed, cancelled, stale, ambiguous) and to warn contributors about bounties that are no longer actionable.
API endpoints are available to list bounties (GET /v1/bounties), retrieve a specific bounty advisory (GET /v1/bounties/:id/advisory), and list bounty lifecycle events (GET /v1/bounties/:id/lifecycle) (src/api/routes.ts).
Rules Engine (src/rules/)#
The rules engine builds structured advisory findings for repositories, pull requests, and issues (advisory.ts).
The buildRepositoryAdvisory() function generates an advisory for a repository, checking whether it is in the local index and whether it is registered in the Gittensor registry (src/rules/advisory.ts). If the repository is registered, the function evaluates its configuration quality, such as whether issue discovery is enabled, whether a maintainer cut is configured, and whether label multipliers are present.
The buildPullRequestAdvisory() function evaluates a pull request for linked issue presence, duplicate risk, queue congestion, and label context (src/rules/advisory.ts). It checks whether the PR is linked to an issue that is already referenced by another open PR, which is a strong indicator of duplicate work (src/rules/advisory.ts). It also flags PRs authored by maintainers (based on GitHub's author association field) to separate maintainer-lane work from normal contributor evidence (src/rules/advisory.ts).
The buildIssueAdvisory() function evaluates an issue for linked PR presence and lane configuration (src/rules/advisory.ts). If the issue already has linked PRs, it warns contributors to avoid duplicate work unless the linked PR is abandoned or incomplete (src/rules/advisory.ts).
All advisory functions generate findings with severity levels (info, warning, critical), titles, details, and optional actions. Findings are stored in the advisories table and used to populate GitHub comments, check runs, and API responses.
MCP Module (src/mcp/)#
The MCP module exposes Gittensory as an MCP server for AI agents and IDE tooling (server.ts, 1077 lines).
The GittensoryMcp class registers ~25 tools, including (src/mcp/server.ts):
- Repo context tools:
gittensory_get_repo_contextreturns registration, lane, queue health, collisions, and config quality for a repository. - Contributor tools:
gittensory_get_contributor_profilereturns an evidence-backed profile,gittensory_get_decision_packreturns a canonical decision pack for private use, andgittensory_monitor_open_prsinspects a contributor's open PRs. - Preflight tools:
gittensory_preflight_prandgittensory_preflight_local_diffcheck for lane correctness, duplicate risk, linked issues, and review burden before submission. - Scoring tools:
gittensory_preview_local_pr_scoreandgittensory_compare_pr_variantsreturn private scoring previews without requiring source code uploads. - Agent tools:
gittensory_agent_plan_next_work,gittensory_agent_start_run, andgittensory_agent_get_runorchestrate the deterministic base-agent planner for contributors. - Local branch tools:
gittensory_preflight_current_branch,gittensory_preview_current_branch_score, andgittensory_explain_local_blockersanalyze current-branch metadata supplied by a local MCP wrapper. - Utility tools:
gittensory_get_registry_changesreturns the diff between the latest cached registry snapshots,gittensory_get_upstream_driftreturns private upstream Gittensor ruleset drift status, andgittensory_get_issue_qualityranks open issues for actionability.
The MCP server enforces session-scoped access controls: session-authenticated users can only query their own login data (src/mcp/server.ts). This prevents unauthorized access to private contributor profiles and decision packs.
The module is exposed via HTTP at ALL /mcp (src/api/routes.ts) and is also packaged as a local stdio MCP server in the @jsonbored/gittensory-mcp package (packages/gittensory-mcp/package.json).
GitHub Integration (src/github/)#
The GitHub integration module manages GitHub App authentication, check run publishing, webhooks, commands, comments, labels, and backfill operations (app.ts).
The createInstallationToken() function creates a short-lived GitHub installation token by first signing a JWT with the GitHub App's private key, then exchanging it for an installation token via the GitHub API (src/github/app.ts). The JWT is signed with RS256 using the app ID and private key from environment variables (src/github/app.ts).
The createOrUpdateCheckRun() function publishes check runs to pull requests (src/github/app.ts). It first queries GitHub for an existing check run with the name "Gittensory" on the PR's head SHA. If one exists, it updates it; otherwise, it creates a new check run. The check run includes a title, summary, and conclusion derived from the advisory findings, but the public text is intentionally minimal—detailed findings are only available via private API or MCP surfaces.
Webhooks are received at POST /v1/github/webhook, verified with the GitHub webhook secret, and then queued as github-webhook jobs for async processing (src/api/routes.ts). The queue processor upserts installation, repository, pull request, and issue data, builds advisory findings, and optionally publishes public surfaces (comments, labels, check runs) based on repository settings.
The GitHub integration module also includes functions for backfilling open data (issues, pull requests, labels) and fetching public contributor profiles via the GitHub API without requiring installation tokens.
The browser extension endpoint GET /v1/extension/pull-context returns PR context for the GitHub UI overlay (src/api/routes.ts).
Authentication (src/auth/)#
The authentication module implements GitHub OAuth 2.0 with both device flow and web flow (github-oauth.ts).
The device flow is designed for CLI tools and headless environments. startGitHubDeviceFlow() initiates the flow by requesting a device code from GitHub (src/auth/github-oauth.ts). The client displays a user code and verification URI, and the user authorizes the device in a browser. pollGitHubDeviceFlow() polls GitHub's token endpoint until the user completes authorization, at which point it exchanges the device code for an access token and creates a session (src/auth/github-oauth.ts).
The web flow is designed for browser-based applications. startGitHubWebOAuth() generates a state parameter (signed with HMAC-SHA256 using the client secret) and redirects the user to GitHub's authorization URL (src/auth/github-oauth.ts). After the user authorizes, GitHub redirects back to the callback URL with a code and state. completeGitHubWebOAuth() verifies the state parameter, exchanges the code for an access token, and creates a session (src/auth/github-oauth.ts).
Both flows call createSessionFromGitHubToken(), which fetches the user's GitHub profile to confirm the login, then creates a session record in the authSessions table (src/auth/github-oauth.ts). The session includes a token hash (for safe storage), login, GitHub user ID, scopes, expiration time, and metadata.
The authentication middleware supports multiple mechanisms (src/api/routes.ts):
- Session tokens for web UI users (extracted from the Authorization header or a cookie).
- Internal service tokens for protected
/v1/internal/*routes. - Extension-scoped tokens for the browser extension, issued via
POST /v1/auth/extension/session.
Rate limiting is enforced via a Durable Object named RateLimiter (wrangler.jsonc), which tracks request counts per actor and applies sliding window rate limits.
Testing#
Gittensory maintains a rigorous testing posture, enforcing a 97% code coverage threshold across all metrics.
Framework#
Tests are written with Vitest v4.1.7 , with coverage provided by @vitest/coverage-v8. Two separate Vitest configurations exist to support different runtime environments :
vitest.config.ts— Standard Node.js test runner for unit and integration testsvitest.workers.config.ts— Cloudflare Workers test runner using@cloudflare/vitest-pool-workers, which executes tests inside the Workers runtime
Coverage Requirements#
All four coverage dimensions are enforced at 97% :
| Metric | Threshold |
|---|---|
| Lines | 97% |
| Functions | 97% |
| Branches | 97% |
| Statements | 97% |
Coverage is scoped to src/**/*.ts and excludes the ambient type declaration src/env.d.ts.
Test Types#
| Script | Purpose |
|---|---|
test:unit | Fast unit tests in Node.js environment |
test:integration | Integration tests with real service boundaries |
test:workers | Tests executed inside the Cloudflare Workers runtime |
test:upstream-contract | Contract tests validating upstream Gittensor API compatibility |
test:smoke:production | Smoke tests against the live production deployment |
test:smoke:browser | Browser automation tests via Playwright |
test:ci | Full CI test suite combining all test types |
test:coverage | Generate and display the coverage report |
test:watch | Interactive watch mode for local development |
Cloudflare Stubs#
The Node.js test environment uses module aliases to stub out Cloudflare-specific imports :
// vitest.config.ts alias configuration
'cloudflare:email' → test/stubs/cloudflare-email.ts
'cloudflare:workers' → test/stubs/cloudflare-workers.ts
This allows the majority of business logic to be tested in a fast Node.js context without requiring the full Workers runtime, while the test:workers suite validates actual Workers API surface compatibility.
Running Tests#
# Run all tests
npm test
# Run with coverage report
npm run test:coverage
# Run only unit tests
npm run test:unit
# Run CI test suite
npm run test:ci
# Validate (typecheck + coverage)
npm run validate
The validate script is the canonical pre-merge gate — it runs TypeScript type checking followed by the full coverage report .
Tooling & Development#
Language & Runtime#
| Tool | Version | Notes |
|---|---|---|
| TypeScript | ^5.9.3 | Full type safety across the entire stack |
| Node.js | ≥22.0.0 | Required for all local development and the MCP CLI |
| npm | 10.9.2 | Workspace-aware package manager |
An .nvmrc file at the repository root pins the recommended Node.js version for contributors .
Build Tools#
| Tool | Purpose |
|---|---|
| Wrangler ^4.95.0 | Cloudflare Workers dev server, type generation, and deployment |
| Vite | UI application build and dev server |
| tsx ^4.22.4 | Execute TypeScript files directly (scripts, utilities) |
Key build commands :
npm run dev # Start Workers dev server
npm run ui:dev # Start UI dev server
npm run build:mcp # Build the MCP CLI package
npm run ui:build # Build UI (includes OpenAPI spec generation)
npm run cf-typegen # Regenerate Cloudflare Worker type bindings
Database Tooling#
Drizzle Kit manages the schema lifecycle :
npm run drizzle:generate # Generate migration files from schema changes
npm run db:migrate:local # Apply migrations to local D1 database
npm run db:migrate:remote # Apply migrations to production D1 database
Code Quality#
npm run typecheck # TypeScript type checking (root)
npm run ui:typecheck # TypeScript type checking (UI)
npm run ui:lint # ESLint for UI
npm run actionlint # Validate GitHub Actions workflow files
OpenAPI#
npm run ui:openapi # Generate OpenAPI spec from backend routes
npm run ui:openapi:check # Validate spec is up-to-date (CI gate)
Changelog#
The project uses git-cliff for automated changelog generation, with separate configuration files for the root and MCP package :
cliff.toml— Root project changelogcliff.mcp.toml—@jsonbored/gittensory-mcppackage changelog
npm run changelog # Generate root changelog
npm run changelog:mcp # Generate MCP package changelog
npm run changelog:check # Verify changelogs are up-to-date
Dependency Management#
Renovate is configured via renovate.json for automated dependency update pull requests.
CI/CD#
GitHub Actions workflows live in .github/ . The primary CI pipeline runs:
npm run typecheck— Type checkingnpm run test:ci— Full test suitenpm run validate— Coverage gate (97% threshold)npm run changelog:check— Changelog validation- Deployment steps via
wrangler deployandnpm run ui:deploy
Deployment Architecture#
Gittensory is deployed across multiple platforms, each serving a distinct role in the system's architecture. The backend runs on Cloudflare's edge network, the frontend is delivered through Cloudflare Pages, the MCP package is distributed via npm, and the browser extension is distributed through the Chrome Web Store.
Backend (Cloudflare Workers)#
The backend deploys as a Cloudflare Worker named gittensory-api (wrangler.jsonc) and serves at gittensory-api.aethereal.dev (wrangler.jsonc). The worker configuration enables smart placement for automatic global edge routing (wrangler.jsonc) and nodejs_compat for Node.js API compatibility (wrangler.jsonc).
Observability: The worker runs with 100% head sampling for both logs and traces, enabling full observability of all requests (wrangler.jsonc).
Database: The D1 database binding DB connects to the database named gittensory (wrangler.jsonc). Migrations are stored in the ./migrations directory (wrangler.jsonc) and applied via npm run db:migrate:local or npm run db:migrate:remote (package.json).
Durable Objects: The RateLimiter Durable Object is bound as RATE_LIMITER and provides distributed rate limiting (wrangler.jsonc).
Queues: The gittensory-jobs queue handles asynchronous job processing with a producer binding JOBS (wrangler.jsonc). The consumer is configured to process up to 10 messages per batch with a 5-second timeout (wrangler.jsonc).
Cron: Scheduled jobs run every 30 minutes via the cron trigger */30 * * * * (wrangler.jsonc).
Deployment: Deploy the backend with npm run deploy or npm run deploy:api (package.json).
Frontend (TanStack Start)#
The frontend is built with TanStack Start and deployed to https://gittensory.aethereal.dev/ (Gittensory website). The build process includes OpenAPI generation and extension bundling via npm run ui:build (package.json), which invokes ui:openapi, extension:build, and the UI workspace build.
Deployment: Deploy the frontend with npm run ui:deploy (package.json), which builds the application and then deploys the output using wrangler deploy --config apps/gittensory-ui/dist/server/wrangler.json (package.json).
MCP Package#
The MCP package is published to npm as @jsonbored/gittensory-mcp (package.json). The package provides a CLI binary gittensory-mcp (package.json) and requires Node.js ≥22.0.0 (package.json).
Build: Build the MCP package with npm run build:mcp (package.json), which validates the main entry points.
Validation: Test the package structure before publishing with npm run test:mcp-pack (package.json).
Release validation: Run npm run test:release:mcp (package.json) to validate the full release including tests, coverage, and changelog checks.
Browser Extension#
The browser extension is a Manifest V3 Chrome extension named "Gittensory Maintainer Overlay" (manifest.json). It connects to https://gittensory-api.aethereal.dev/* (manifest.json) to fetch pull request context for GitHub PR and issue pages (manifest.json).
The extension is built with npm run extension:build and packaged as gittensory-extension.zip under apps/gittensory-ui/public/downloads/. The content script uses ES6 modules ("type": "module") to import github-target.js (URL parsing) and overlay-safety.js (forbidden term redaction, HTML escaping, source upload enforcement). Issue pages display a scaffold notice; pull request pages load private reviewability context from the API.
CI/CD Pipeline#
The CI/CD pipeline is orchestrated through GitHub Actions and npm scripts:
Test suite: The test:ci script (package.json) runs the full test suite including:
- Git diff check for whitespace issues
- GitHub Actions linting with
actionlint - TypeScript type checking
- Test coverage (unit, integration, workers)
- MCP package build and validation
- OpenAPI spec generation check
- UI linting, type checking, and build
- npm audit with moderate threshold
Release validation: The test:release script (package.json) runs test:ci plus changelog validation.
Production smoke tests: After deployment, run npm run test:smoke:production (package.json) to verify the production environment.
Browser smoke tests: Run npm run test:smoke:browser (package.json) using Playwright to test the UI in a browser environment.
Environment Variables#
Environment variables are configured in the vars section of wrangler.jsonc (wrangler.jsonc) and include:
- GitHub App credentials (app ID, OAuth client ID)
- Gittensor upstream repository and registry URLs
- Public API and site origins
- AI feature toggles and model configuration
- Admin GitHub logins
Sensitive values like private keys and secrets are managed through Cloudflare's secrets management system and are not stored in the configuration file.
Module Interactions#
Gittensory's architecture flows through five primary interaction patterns that coordinate the backend Workers, database, frontend, GitHub App, and AI agent integrations. Data flows from external triggers (HTTP requests, GitHub webhooks, cron schedules) through the Cloudflare Workers runtime, into specialized modules, and back out through three distinct output surfaces.
HTTP Request Flow (Frontend → Backend → DB)#
The TanStack Start frontend at https://gittensory.aethereal.dev/ makes HTTP requests to the Cloudflare Workers API at https://gittensory-api.aethereal.dev/. The Workers runtime receives requests via the fetch handler in src/index.ts, which routes them through the Hono web framework to src/api/routes.ts.
Authentication middleware validates sessions or bearer tokens before route handlers execute . Route handlers invoke domain modules—signals, scoring, bounties, registry, or GitHub integration—to process requests. These modules query and persist data through the repository pattern in src/db/repositories.ts, which abstracts access to the Cloudflare D1 SQLite database.
Responses flow back through Hono middleware as JSON payloads to the frontend, where TanStack Query caches and renders them in React components.
GitHub Webhook Processing Pipeline#
When a GitHub App event occurs (PR opened, issue created, push), GitHub sends a webhook to POST /v1/github/webhook . The webhook handler validates the signature, stores the event in the webhookEvents table, and enqueues a job to the gittensory-jobs queue .
The queue consumer picks up batches via the Cloudflare Workers queue handler , which routes jobs to src/queue/processors.ts. Each processor matches a JobMessage type and invokes the appropriate module. For webhook jobs, the GitHub integration module in src/github/ processes the event and calls into the signals engine at src/signals/engine.ts to generate analysis.
The signals engine builds collision reports, queue health assessments, contributor profiles, and preflight checks . Results are published back to GitHub as comments, labels, or check runs, and snapshots are persisted to tables like signalSnapshots and database advisory records.
Scoring & Bounty Calculation Flow#
A Cloudflare Workers cron trigger fires every 30 minutes (*/30 * * * *) , invoking the scheduled handler in src/index.ts. This handler enqueues periodic jobs with different intervals:
-
Every hour:
refresh-scoring-modeljob → src/scoring/model.ts fetches scoring constants and programming language weights from the upstream Gittensor repository . TherefreshScoringModelSnapshot()function parses Python constants, detects the active model (saturation vs. density), and persists the snapshot to thescoringModelSnapshotstable . -
Every hour:
refresh-registryjob → src/registry/sync.ts probes multiple API endpoints and a fallback GitHub URL to fetch the Gittensor registry . TherefreshRegistry()function normalizes allocation shares, label multipliers, and maintainer cuts, then persists them toregistrySnapshotsand updates therepositoriestable . -
Every 6 hours:
generate-signal-snapshotsjob → signals engine builds comprehensive snapshots for all registered repos, combining collision reports, queue health, and contributor profiles.
Bounty data is ingested separately via src/bounties/ingest.ts, which normalizes responses from the external Gitt bounty service into BountyRecord objects . These are stored in the bounties and bountyLifecycleEvents tables.
When a user requests a score preview via the API, the scoring module combines the latest scoringModelSnapshot, registry data, and contributor evidence to return an estimate without requiring source code upload.
MCP Command Execution Flow#
AI agents (Cursor, Claude Desktop, Codex) connect to the @jsonbored/gittensory-mcp package via stdio . The MCP package runs locally in the developer's environment, collecting git metadata—changed files, commit messages, linked issues—without uploading source code .
When an agent invokes a tool (e.g., gittensory_preflight_pr), the MCP package sends an HTTP request to https://gittensory-api.aethereal.dev/. The backend authenticates the request using a bearer token from the GITTENSORY_API_TOKEN environment variable or a stored session file .
Requests hit either the unified ALL /mcp endpoint or specific REST API endpoints like /v1/preflight/pr. The MCP server in src/mcp/server.ts registers approximately 25 tools , each mapping to a method that queries the database and invokes the signals engine or scoring module.
The backend returns a structured JSON response to the MCP package via stdio, which the agent consumes to guide the developer with actionable insights about PR readiness, collision risk, score estimates, and next steps.
Browser Extension Flow#
The Gittensory Chrome extension injects a content script on github.com PR and issue pages . The content script uses ES6 module imports to load github-target.js for URL detection and overlay-safety.js for security enforcement.
When a maintainer views a PR or issue, parseGitHubPageTarget() from github-target.js parses the pathname into a structured target ({kind: "pull", owner, repo, pullNumber} or {kind: "issue", owner, repo, issueNumber}). For PR pages, the service worker sends an authenticated request to GET /v1/extension/pull-context at https://gittensory-api.aethereal.dev/ .
The backend retrieves maintainer packet data—collision reports, queue health, scoring context—and returns it as JSON. renderOverlayPanels() from overlay-safety.js sanitizes the response by redacting forbidden terms (wallet, hotkey, coldkey, mnemonic, private paths) via isOverlayDisplaySafe() and redactForOverlayDisplay(), then escapes HTML with escapeOverlayHtml() to prevent XSS. The content script renders the sanitized overlay in the GitHub UI. Issue pages display a scaffold notice directing users to the linked PR for full context. EXTENSION_SOURCE_UPLOAD_ENABLED is hardcoded to false, enforcing that the extension never uploads source code.
Output Surfaces#
Gittensory exposes three distinct output surfaces:
-
GitHub App: Comments, labels, and check runs appear directly on PRs and issues. The GitHub integration module publishes findings to help maintainers and contributors understand scoring potential, collision risk, and queue health.
-
MCP Server: AI agents access Gittensory intelligence through both the
/mcpendpoint and the@jsonbored/gittensory-mcpstdio package. Tools provide preflight checks, contributor profiles, score previews, and decision packs to guide coding agents in planning contributions. -
REST API + Web UI: The web dashboard at https://gittensory.aethereal.dev/ offers visualizations for miners, maintainers, and operators. REST endpoints expose repo context, burden forecasts, registry changes, and upstream drift status for programmatic access.
These surfaces share a common backend but serve different audiences: GitHub App for in-context maintainer guidance, MCP for AI-driven developer workflows, and REST API for analytics and operational monitoring.