Open Source Development Team Operation Analytics
Project description
dev-health-ops
Open source analytics for developer health and team operating modes.
Dev Health Ops ingests engineering activity from Git providers, work trackers,
deployments, incidents, and local repositories; normalizes it into persisted
evidence; computes inspectable metrics; and serves those metrics to the
GraphQL/API layer used by dev-health-web.
Why this exists
Developer health tooling often drifts into expensive, opaque scorecards that are easy to misuse. This project is intentionally different:
- Accessibility over extraction: derive insight from data teams already own.
- Learning, not judgment: show operating signals, not individual rankings.
- Trends over absolutes: emphasize change over time and distributions.
- Inspectable by default: metrics trace back to schemas, queries, and evidence.
Non-goals:
- Individual leaderboards or performance scores
- HR/performance-management workflows
- Dashboards that hide definitions, provenance, or missing data
Current architecture
Dev Health Ops follows a strict pipeline boundary:
Providers → Processors → Sinks → Metrics → API / Visualization
- Providers fetch raw provider data from GitHub, GitLab, Jira, Linear, local Git, CI/CD, deployments, incidents, and synthetic/demo sources.
- Processors normalize provider records into internal models.
- Sinks persist computed outputs. Analytics persistence is ClickHouse-only.
- Metrics jobs compute daily rollups, DORA, complexity, risk, investment, AI workflow, and work graph outputs from persisted data.
- API/GraphQL serves persisted analytics to
dev-health-weband other consumers.
The primary visualization surface is now dev-health-web. Grafana is optional,
and this repository no longer ships the old sample dashboard gallery in this
README.
Install
Use the package directly:
pip install dev-health-ops
dev-hops --help
For local development from this repository:
pip install -r requirements.txt
The installed command is dev-hops.
Database model
Dev Health Ops uses two databases with different responsibilities:
| Layer | Backend | Environment variable | Purpose |
|---|---|---|---|
| Semantic | PostgreSQL | POSTGRES_URI |
Users, organizations, settings, credentials |
| Analytics | ClickHouse | CLICKHOUSE_URI |
Commits, PRs/MRs, work items, metrics, graph data |
ClickHouse is required for analytics features. MongoDB, SQLite, and PostgreSQL analytics sinks have been removed or deprecated; SQLite remains only for narrow test/local fixture paths.
Start local services and run migrations:
docker compose up -d postgres clickhouse valkey
export POSTGRES_URI="postgresql+asyncpg://postgres:postgres@localhost:5555/postgres"
export CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default"
dev-hops migrate postgres
dev-hops migrate clickhouse
See docs/architecture/database-architecture.md
and docs/ops/cli-reference.md for details.
Common workflows
Sync source data
# Local git repository
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops sync git --provider local --repo-path /path/to/repo
# GitHub repository
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops sync git --provider github \
--auth "$GITHUB_TOKEN" \
--owner <owner> \
--repo <repo>
# Pull requests
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops sync prs --provider github \
--auth "$GITHUB_TOKEN" \
--owner <owner> \
--repo <repo>
# Work items from Jira, GitHub, GitLab, Linear, synthetic data, or all providers
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops sync work-items --provider all --backfill 30
# Teams into the ClickHouse team catalog (ClickHouse is the system of record)
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops sync teams --provider config --path src/dev_health_ops/config/team_mapping.yaml --allow-empty
The bundled team_mapping.yaml is an empty onboarding sample. sync teams
exits non-zero when no teams are persisted; pass --allow-empty only for
intentional empty/no-op syncs such as validating the sample config.
Provider authentication can come from CLI flags or environment variables such as
GITHUB_TOKEN, GITLAB_TOKEN, JIRA_*, ATLASSIAN_*, and LINEAR_API_KEY.
Compute metrics
# Daily analytics rollups
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops metrics daily --backfill 30
# Complexity and hotspot snapshots for a repository
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops metrics complexity --repo-path /path/to/repo --backfill 30
Generate demo data
dev-hops fixtures generate \
--sink "clickhouse://ch:ch@localhost:8123/default" \
--days 30 \
--with-metrics \
--with-work-graph
Run the API
POSTGRES_URI="postgresql+asyncpg://postgres:postgres@localhost:5555/postgres" \
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
dev-hops api --reload
OpenAPI docs are available at http://localhost:8000/docs when the API is running. GraphQL is served by the API for the web app.
Run workers
Background jobs use Celery with Valkey/Redis:
POSTGRES_URI="postgresql+asyncpg://postgres:postgres@localhost:5555/postgres" \
CLICKHOUSE_URI="clickhouse://ch:ch@localhost:8123/default" \
CELERY_BROKER_URL="redis://localhost:6379/0" \
CELERY_RESULT_BACKEND="redis://localhost:6379/0" \
dev-hops workers start-worker --queues default metrics sync reports
Test tiers
Canonical local test commands:
make test:unit
make test:integration
make test:e2e
make test:live-e2e
make test:ci
All tiers route through one entrypoint:
./ci/run_tests.sh <unit|integration|e2e|live-e2e|ci>
Notes:
integrationis token-aware and skips provider tests cleanly when credentials are unavailable.live-e2estarts a live backend harness, generates deterministic ClickHouse fixtures, waits for API readiness, and asserts/health,/api/v1/meta, and/api/v1/home.ciblocks onflake8and coverage-gated unit tests.black,isort, andmypyare advisory by default; setSTRICT_QUALITY_GATES=1to make them blocking.- JUnit XML paths are stable under
test-results/junit/and can be overridden withTEST_RESULTS_DIR/JUNIT_XML_*variables.
Container images
The repository builds two reusable images from docker/Dockerfile:
| Image | Purpose |
|---|---|
dev-hops-api |
Runs dev-hops api on port 8000 |
dev-hops-runner |
Uses dev-hops as the entrypoint for sync, fixtures, metrics, and maintenance jobs |
Build both images:
IMAGE_REGISTRY=ghcr.io/myorg/dev-health-ops \
VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo latest) \
./scripts/build-images.sh
Run the API image:
docker run --rm -p 8000:8000 \
-e POSTGRES_URI="postgresql+asyncpg://postgres:postgres@postgres:5432/postgres" \
-e CLICKHOUSE_URI="clickhouse://ch:ch@clickhouse:8123/default" \
dev-hops-api:latest
Run a CLI job through the runner image:
docker run --rm -it \
--network dev-health_default \
-v "$(pwd)":/app \
-w /app \
-e CLICKHOUSE_URI="clickhouse://ch:ch@clickhouse:8123/default" \
dev-hops-runner:latest \
metrics daily --backfill 14
Key docs
docs/getting-started.md: setup and demo datadocs/ops/cli-reference.md: full CLI referencedocs/architecture/database-architecture.md: PostgreSQL/ClickHouse splitdocs/architecture/data-pipeline.md: provider → processor → sink boundariesdocs/product/prd.md: product intent and guardrailsdocs/user-guide/investment-view.md: canonical Investment Viewdocs/user-guide/reports.md: Report Center and scheduled reports
Guardrails
- WorkUnits are evidence containers, not categories.
- Investment categorization runs at compute time and persists distributions.
- Theme rollups are deterministic from canonical subcategories.
- UX-time LLM usage is explanation-only and must not recompute categories.
- Analytics persistence goes through ClickHouse sinks, not file exports or debug dumps.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dev_health_ops-1.1.0.tar.gz.
File metadata
- Download URL: dev_health_ops-1.1.0.tar.gz
- Upload date:
- Size: 3.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1cfe8cc8d780b182fcb26e702bc9caf5e8552759000285a27f728dd85f0ade0
|
|
| MD5 |
eb33db4c0012c052194a356688cc1f10
|
|
| BLAKE2b-256 |
1baad5c951b894468865dbb9098d0e0e14dc39b3fa564758363e41295c95f7c7
|
Provenance
The following attestation bundles were made for dev_health_ops-1.1.0.tar.gz:
Publisher:
publish-pypi.yml on full-chaos/dev-health-ops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dev_health_ops-1.1.0.tar.gz -
Subject digest:
c1cfe8cc8d780b182fcb26e702bc9caf5e8552759000285a27f728dd85f0ade0 - Sigstore transparency entry: 2102210478
- Sigstore integration time:
-
Permalink:
full-chaos/dev-health-ops@13c06fe398de785a0a2f89416d2a9ab9df210e93 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/full-chaos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@13c06fe398de785a0a2f89416d2a9ab9df210e93 -
Trigger Event:
release
-
Statement type:
File details
Details for the file dev_health_ops-1.1.0-py3-none-any.whl.
File metadata
- Download URL: dev_health_ops-1.1.0-py3-none-any.whl
- Upload date:
- Size: 2.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bccef3b9dfe3dee384a5d301cecf75a40f4a1d819f671fd7e80888675172581
|
|
| MD5 |
d173fd3698d89e6b33e72961e5824fe8
|
|
| BLAKE2b-256 |
5ee3f6ce56e674bc0bee1e74ff93a76114b339f698790cefa1f42a00b26144a2
|
Provenance
The following attestation bundles were made for dev_health_ops-1.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on full-chaos/dev-health-ops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dev_health_ops-1.1.0-py3-none-any.whl -
Subject digest:
3bccef3b9dfe3dee384a5d301cecf75a40f4a1d819f671fd7e80888675172581 - Sigstore transparency entry: 2102210935
- Sigstore integration time:
-
Permalink:
full-chaos/dev-health-ops@13c06fe398de785a0a2f89416d2a9ab9df210e93 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/full-chaos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@13c06fe398de785a0a2f89416d2a9ab9df210e93 -
Trigger Event:
release
-
Statement type: