Skip to main content

WhyChanged (whychanged)

Production diff-detective. When monitoring tells you something broke, what actually changed?

Why

Production incidents almost always trace back to something that happened in the recent past — a deploy, a feature-flag toggle, a config push, a dependency bump. But your dashboards tell you what's broken, not why. WhyChanged correlates change sources in a time window around an incident and ranks them by likelihood of having caused it.

Status

v0.1.0 beta. Ships the engine + a local Git change provider + the GitHub Deployments cloud provider. Other cloud plugins (LaunchDarkly, Render, Vercel, ArgoCD, Kubernetes events) land in v0.2+.

What v0.0.1 does

  1. Asks every configured ChangeProvider for changes in the requested window.
  2. Scores each change with a deterministic heuristic:
    • Recency — exponential decay relative to the incident time (30-min half-life)
    • File scope — bonus when a change touches files that belong to the affected service
    • Kind weight — schema migrations and config changes outscore feature-flag toggles when all else is equal
  3. Sorts by score and emits a JSON + Markdown report.

CLI

whychanged version

# Rolling 30-minute window from now
whychanged explain --repo .

# Explicit incident time + service scope
whychanged explain --repo . \
  --since 1h \
  --incident-at 2026-05-08T14:30:00+00:00 \
  --service api \
  --service-file src/api/models.py \
  --service-file src/api/views.py

# v0.1: combine local commits with GitHub Deployments events
export WHYCHANGED_GITHUB_TOKEN=ghp_...
whychanged explain --repo . \
  --since 2h \
  --github-repo myorg/api \
  --github-environment production

Output: .whychanged/report.json (versioned, machine-consumable) + .whychanged/report.md (human companion).

Change kinds

Kind Source examples
deploy Git commit on main, container release, cloud build
feature-flag LaunchDarkly / Statsig / homegrown flag toggle
config Kubernetes ConfigMap, env-var change, infra apply
dependency package.json / requirements update, image bump
schema Database migration / schema change
unknown Catch-all for unclassified providers

Roadmap

  • v0.2 — GitHub App installation-token auth + incident-aware webhook receiver: post the top culprit to Slack / Datadog
  • v0.2 — outcome-trained ranker (replaces the deterministic heuristic with a learned model once we have "was the top rank actually the culprit?" data)
  • v0.3 — service-graph integration (rank higher when a change is upstream of the affected service)

Apache-2.0 license. See CHANGELOG.

Metadata

Release files for devtrust-whychanged 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for devtrust-whychanged 0.1.0
File Size Uploaded
devtrust_whychanged-0.1.0.tar.gz 19.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for devtrust-whychanged 0.1.0
File Interpreter ABI Platform
devtrust_whychanged-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.7 kB

Release files / devtrust_whychanged-0.1.0.tar.gz

Download URL devtrust_whychanged-0.1.0.tar.gz
Size 19.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3156c8ad60a18cf981e2c2aa0e14f1dc802670e18600325c22c1e2f36c5f275e
BLAKE2b-256 checksum
How to use checksums
730a1ad550723d798f1083d23091a409192165a2e51a8d0578496464af6dcca3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 9, 2026.

Transparency log

Release files / devtrust_whychanged-0.1.0-py3-none-any.whl

Download URL devtrust_whychanged-0.1.0-py3-none-any.whl
Size 16.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
423dde37755d18a4b5f595d527bc64a3d70972d65f0d08ffb7d84de890e36905
BLAKE2b-256 checksum
How to use checksums
67181040da8b4ad1a2105fb421e9c7cb9f698a4aff4196b8fe07b08abe88413b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page