{"id":15063995,"url":"https://github.com/superlinear-ai/conformal-tights","last_synced_at":"2025-10-11T20:45:14.439Z","repository":{"id":225335261,"uuid":"765698489","full_name":"superlinear-ai/conformal-tights","owner":"superlinear-ai","description":"👖 Conformal Tights adds conformal prediction of coherent quantiles and intervals to any scikit-learn regressor or Darts forecaster","archived":false,"fork":false,"pushed_at":"2025-05-01T09:23:49.000Z","size":878,"stargazers_count":112,"open_issues_count":7,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-25T11:48:50.479Z","etag":null,"topics":["conformal-prediction","forecasting","machine-learning","prediction-intervals","python","quantile-regression","scikit-learn","time-series-forecasting"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/superlinear-ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-01T12:49:15.000Z","updated_at":"2025-08-12T11:02:42.000Z","dependencies_parsed_at":"2024-03-01T14:28:03.612Z","dependency_job_id":"1243ac9b-4211-47bc-8c55-0a37aeeb6571","html_url":"https://github.com/superlinear-ai/conformal-tights","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"86ceafc884a939bb8ebfac2468a1b7d967fee740"},"previous_names":["radix-ai/conformal-tights","superlinear-ai/conformal-tights"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/superlinear-ai/conformal-tights","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superlinear-ai%2Fconformal-tights","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superlinear-ai%2Fconformal-tights/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superlinear-ai%2Fconformal-tights/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superlinear-ai%2Fconformal-tights/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/superlinear-ai","download_url":"https://codeload.github.com/superlinear-ai/conformal-tights/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superlinear-ai%2Fconformal-tights/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279008630,"owners_count":26084480,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conformal-prediction","forecasting","machine-learning","prediction-intervals","python","quantile-regression","scikit-learn","time-series-forecasting"],"created_at":"2024-09-25T00:09:55.016Z","updated_at":"2025-10-11T20:45:14.392Z","avatar_url":"https://github.com/superlinear-ai.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers\u0026message=Open\u0026color=blue\u0026logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE3IDE2VjdsLTYgNU0yIDlWOGwxLTFoMWw0IDMgOC04aDFsNCAyIDEgMXYxNGwtMSAxLTQgMmgtMWwtOC04LTQgM0gzbC0xLTF2LTFsMy0zIi8+PC9zdmc+)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/superlinear-ai/conformal-tights) [![Open in GitHub Codespaces](https://img.shields.io/static/v1?label=GitHub%20Codespaces\u0026message=Open\u0026color=blue\u0026logo=github)](https://github.com/codespaces/new/superlinear-ai/conformal-tights)\n\n# 👖 Conformal Tights\n\nConformal Tights is a Python package for Coherent Conformal Prediction\u003csup\u003e✦\u003c/sup\u003e that exports:\n\n1. 🍬 a scikit-learn [meta-estimator](https://scikit-learn.org/stable/glossary.html#term-meta-estimator) that adds coherent [conformal](https://en.wikipedia.org/wiki/Conformal_prediction) prediction of [quantiles](https://en.wikipedia.org/wiki/Quantile) and [intervals](https://en.wikipedia.org/wiki/Prediction_interval) to any [scikit-learn regressor](https://scikit-learn.org/stable/glossary.html#term-regressor)\n2. 🔮 a Darts [forecaster](https://unit8co.github.io/darts/generated_api/darts.models.forecasting.regression_model.html) that adds coherent conformal [probabilistic time series forecasting](https://unit8co.github.io/darts/userguide/forecasting_overview.html#probabilistic-forecasts) to any scikit-learn regressor\n\n## Features\n\n\u003e [!TIP]\n\u003e \u003csup\u003e✦\u003c/sup\u003eCoherent Conformal Prediction (CCP): what makes Conformal Tights unique is that it produces so-called _coherent_ conformally calibrated quantile predictions. Without coherence, a model's predicted quantiles may cross each other in practice. For instance, the 25th percentile prediction may be higher than the 75th percentile prediction. With coherence, the predicted quantiles increase monotonically as you would expect.\n\n1. 🚦 **Coherent:** quantiles increase monotonically instead of [crossing](https://github.com/dmlc/xgboost/issues/9848) [each other](https://github.com/microsoft/LightGBM/issues/3447)\n2. 🌡️ **Conformal:** prediction intervals with reliable [coverage](https://en.wikipedia.org/wiki/Coverage_probability) and accurate quantile predictions\n3. 🪜 **Dynamic:** two-level conformal calibration of both absolute and relative residuals\n4. 👖 **Tight:** selects the lowest [dispersion](https://en.wikipedia.org/wiki/Statistical_dispersion) that provides the desired coverage\n5. 🎁 **Data efficient:** requires only a small number of calibration examples to fit\n6. 🐼 **Pandas support:** optionally predict on DataFrames and receive DataFrame output\n\n## Using\n\n### Quick links\n\n1. [Installing](#installing)\n2. [Predicting quantiles](#predicting-quantiles)\n3. [Predicting intervals](#predicting-intervals)\n4. [Forecasting time series](#forecasting-time-series)\n\n### Installing\n\n```sh\npip install conformal-tights\n```\n\n### Predicting quantiles\n\nConformal Tights exports a meta-estimator called `ConformalCoherentQuantileRegressor` that you can use to equip any scikit-learn regressor with a `predict_quantiles` method that predicts conformally calibrated quantiles. Example usage:\n\n```python\nfrom conformal_tights import ConformalCoherentQuantileRegressor\nfrom sklearn.datasets import fetch_openml\nfrom sklearn.model_selection import train_test_split\nfrom xgboost import XGBRegressor\n\n# Fetch dataset and split in train and test\nX, y = fetch_openml(\"ames_housing\", version=1, return_X_y=True, as_frame=True, parser=\"auto\")\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=42)\n\n# Create a regressor, equip it with conformal prediction, and fit on the train set\nmy_regressor = XGBRegressor(objective=\"reg:absoluteerror\")\nconformal_predictor = ConformalCoherentQuantileRegressor(estimator=my_regressor)\nconformal_predictor.fit(X_train, y_train)\n\n# Predict with the underlying regressor\nŷ_test = conformal_predictor.predict(X_test)\n\n# Predict quantiles with the conformal predictor\nŷ_test_quantiles = conformal_predictor.predict_quantiles(\n    X_test, quantiles=(0.025, 0.05, 0.1, 0.5, 0.9, 0.95, 0.975)\n)\n```\n\nWhen the input data is a pandas DataFrame, the output is also a pandas DataFrame. For example, printing the head of `ŷ_test_quantiles` yields:\n\n|   house_id |    0.025 |     0.05 |      0.1 |      0.5 |      0.9 |     0.95 |    0.975 |\n|-----------:|---------:|---------:|---------:|---------:|---------:|---------:|---------:|\n|       1357 | 114743.7 | 120917.9 | 131752.6 | 156708.2 | 175907.8 | 187996.1 | 205443.4 |\n|       2367 |  67382.7 |  80191.7 |  86871.8 | 105807.1 | 118465.3 | 127581.2 | 142419.1 |\n|       2822 | 119068.0 | 131864.8 | 138541.6 | 159447.7 | 179227.2 | 197337.0 | 214134.1 |\n|       2126 |  93885.8 | 100040.7 | 111345.5 | 134292.7 | 150557.1 | 164595.8 | 182524.1 |\n|       1544 |  68959.8 |  81648.8 |  88364.1 | 108298.3 | 122329.6 | 132421.1 | 147225.6 |\n\nLet's visualize the predicted quantiles on the test set:\n\n\u003cimg src=\"https://github.com/superlinear-ai/conformal-tights/assets/4543654/2726d108-ee84-47d0-83d9-7e911b123f0c\"\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to see the code that generated the graph above\u003c/summary\u003e\n\n```python\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as ticker\n\n%config InlineBackend.figure_format = \"retina\"\nplt.rc(\"font\", family=\"DejaVu Sans\", size=10)\nplt.figure(figsize=(8, 4.5))\nidx = ŷ_test_quantiles[0.5].sample(50, random_state=42).sort_values().index\nx = list(range(1, len(idx) + 1))\nx_ticks = [1, *list(range(5, len(idx) + 1, 5))]\nfor j in range(3):\n    coverage = round(100 * (ŷ_test_quantiles.columns[-(j + 1)] - ŷ_test_quantiles.columns[j]))\n    plt.bar(\n        x,\n        ŷ_test_quantiles.loc[idx].iloc[:, -(j + 1)] - ŷ_test_quantiles.loc[idx].iloc[:, j],\n        bottom=ŷ_test_quantiles.loc[idx].iloc[:, j],\n        color=[\"#b3d9ff\", \"#86bfff\", \"#4da6ff\"][j],\n        label=f\"{coverage}% Prediction interval\",\n    )\nplt.plot(\n    x,\n    y_test.loc[idx],\n    \"s\",\n    label=\"Actual (test)\",\n    markeredgecolor=\"#e74c3c\",\n    markeredgewidth=1.414,\n    markerfacecolor=\"none\",\n    markersize=4,\n)\nplt.plot(x, ŷ_test.loc[idx], \"s\", color=\"blue\", label=\"Predicted (test)\", markersize=2)\nplt.xlabel(\"House\")\nplt.xticks(x_ticks, x_ticks)\nplt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f\"${x/1000:,.0f}k\"))\nplt.gca().tick_params(axis=\"both\", labelsize=10)\nplt.gca().spines[\"top\"].set_visible(False)\nplt.gca().spines[\"right\"].set_visible(False)\nplt.grid(False)\nplt.grid(axis=\"y\")\nplt.legend(loc=\"upper left\", title=\"House price\", title_fontproperties={\"weight\": \"bold\"})\nplt.tight_layout()\n```\n\n\u003c/details\u003e\n\n### Predicting intervals\n\nIn addition to quantile prediction, you can use `predict_interval` to predict conformally calibrated prediction intervals. Compared to quantiles, these focus on reliable coverage over quantile accuracy. Example usage:\n\n```python\n# Predict an interval for each example with the conformal predictor\nŷ_test_interval = conformal_predictor.predict_interval(X_test, coverage=0.95)\n\n# Measure the coverage of the prediction intervals on the test set\ncoverage = ((ŷ_test_interval.iloc[:, 0] \u003c= y_test) \u0026 (y_test \u003c= ŷ_test_interval.iloc[:, 1])).mean()\nprint(coverage)  # 96.6%\n```\n\nWhen the input data is a pandas DataFrame, the output is also a pandas DataFrame. For example, printing the head of `ŷ_test_interval` yields:\n\n|   house_id |    0.025 |    0.975 |\n|-----------:|---------:|---------:|\n|       1357 | 107202.8 | 206290.4 |\n|       2367 |  66665.1 | 146004.8 |\n|       2822 | 115591.8 | 220314.8 |\n|       2126 |  85288.1 | 183037.8 |\n|       1544 |  67889.9 | 150646.2 |\n\n### Forecasting time series\n\nConformal Tights also exports a Darts forecaster called `DartsForecaster` that uses a `ConformalCoherentQuantileRegressor` to make conformally calibrated probabilistic time series forecasts. To demonstrate its usage, let's begin by loading a time series dataset:\n\n```python\nfrom darts.datasets import ElectricityConsumptionZurichDataset\n\n# Load a forecasting dataset\nts = ElectricityConsumptionZurichDataset().load()\nts = ts.resample(\"h\")\n\n# Split the dataset into covariates X and target y\nX = ts.drop_columns([\"Value_NE5\", \"Value_NE7\"])\ny = ts[\"Value_NE5\"]  # NE5 = Household energy consumption\n\n# Add categorical covariates to X\nX = X.add_holidays(country_code=\"CH\")\nX = X.add_datetime_attribute(\"month\")\nX = X.add_datetime_attribute(\"dayofweek\")\nX = X.add_datetime_attribute(\"hour\")\nX_categoricals = [\"holidays\", \"month\", \"dayofweek\", \"hour\"]\n```\n\nPrinting the tail of the covariates time series `X.pd_dataframe()` yields:\n\n| Timestamp      |   Hr [%Hr] |   RainDur [min] |   StrGlo [W/m2] |   T [°C] |   WD [°] |   WVs [m/s] |   WVv [m/s] |   p [hPa] |   holidays |   month |   dayofweek |   hour |\n|:---------------|-----------:|----------------:|----------------:|---------:|---------:|------------:|------------:|----------:|-----------:|--------:|------------:|-------:|\n| 2022‑08‑30 20h |       70.2 |             0.0 |             0.0 |     19.9 |    290.2 |         1.7 |         1.5 |     968.5 |        0.0 |     7.0 |         1.0 |   20.0 |\n| 2022‑08‑30 21h |       70.1 |             0.0 |             0.0 |     19.5 |    239.2 |         1.0 |         0.7 |     968.1 |        0.0 |     7.0 |         1.0 |   21.0 |\n| 2022‑08‑30 22h |       71.3 |             0.0 |             0.0 |     19.5 |     28.9 |         1.5 |         1.3 |     967.9 |        0.0 |     7.0 |         1.0 |   22.0 |\n| 2022‑08‑30 23h |       80.4 |             0.0 |             0.0 |     18.9 |     24.3 |         1.6 |         1.1 |     967.9 |        0.0 |     7.0 |         1.0 |   23.0 |\n| 2022‑08‑31 00h |       81.6 |             1.0 |             0.0 |     18.7 |    293.5 |         0.9 |         0.3 |     967.8 |        0.0 |     7.0 |         2.0 |    0.0 |\n\nWe can now equip a scikit-learn regressor with conformal prediction using `ConformalCoherentQuantileRegressor` as before, and then equip that conformal predictor with probabilistic time series forecasting using `DartsForecaster`:\n\n```python\nfrom conformal_tights import DartsForecaster, ConformalCoherentQuantileRegressor\nfrom pandas import Timestamp\nfrom xgboost import XGBRegressor\n\n# Split the dataset into train and test\ntest_cutoff = Timestamp(\"2022-06-01\")\ny_train, y_test = y.split_after(test_cutoff)\nX_train, X_test = X.split_after(test_cutoff)\n\n# Now let's:\n# 1. Create an sklearn regressor of our choosing, in this case `XGBRegressor`\n# 2. Add conformal quantile prediction to the regressor with `ConformalCoherentQuantileRegressor`\n# 3. Add probabilistic forecasting to the conformal predictor with `DartsForecaster`\nmy_regressor = XGBRegressor()\nconformal_predictor = ConformalCoherentQuantileRegressor(estimator=my_regressor)\nforecaster = DartsForecaster(\n    model=conformal_predictor,\n    lags=5 * 24,  # Add the last 5 days of the target to the prediction features\n    lags_future_covariates=[0],  # Add the current timestamp's covariates to the prediction features\n    categorical_future_covariates=X_categoricals,  # Convert these covariates to pd.Categorical\n)\n\n# Fit the forecaster\nforecaster.fit(y_train, future_covariates=X_train)\n\n# Make a probabilistic forecast 5 days into the future by predicting a set of conformally calibrated\n# quantiles at each time step and drawing 500 samples from them\nquantiles = (0.025, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.975)\nforecast = forecaster.predict(\n    n=5 * 24, future_covariates=X_test, num_samples=500, quantiles=quantiles\n)\n```\n\nPrinting the head of the forecast quantiles time series `forecast.quantiles_df(quantiles=quantiles)` yields:\n\n| Timestamp      |   Value_NE5_0.025 |   Value_NE5_0.05 |   Value_NE5_0.1 |   Value_NE5_0.25 |   Value_NE5_0.5 |   Value_NE5_0.75 |   Value_NE5_0.9 |   Value_NE5_0.95 |   Value_NE5_0.975 |\n|:---------------|------------------:|-----------------:|----------------:|-----------------:|----------------:|-----------------:|----------------:|-----------------:|------------------:|\n| 2022‑06‑01 01h |           19165.2 |          19268.3 |         19435.7 |          19663.0 |         19861.7 |          20062.2 |         20237.9 |          20337.7 |           20453.2 |\n| 2022‑06‑01 02h |           19004.0 |          19099.0 |         19226.3 |          19453.7 |         19710.7 |          19966.1 |         20170.1 |          20272.8 |           20366.9 |\n| 2022‑06‑01 03h |           19372.6 |          19493.0 |         19679.4 |          20027.6 |         20324.6 |          20546.3 |         20773.2 |          20910.3 |           21014.1 |\n| 2022‑06‑01 04h |           21936.2 |          22105.6 |         22436.0 |          22917.5 |         23308.6 |          23604.8 |         23871.0 |          24121.7 |           24351.5 |\n| 2022‑06‑01 05h |           25040.5 |          25330.5 |         25531.1 |          25910.4 |         26439.4 |          26903.2 |         27287.4 |          27493.9 |           27633.9 |\n\nLet's visualize the forecast and its prediction interval on the test set:\n\n\u003cimg src=\"https://github.com/superlinear-ai/conformal-tights/assets/4543654/8c3c256f-0732-49c7-94f2-e42213e85e4b\"\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to see the code that generated the graph above\u003c/summary\u003e\n\n```python\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as ticker\n\n%config InlineBackend.figure_format = \"retina\"\nplt.rc(\"font\", family=\"DejaVu Sans\", size=10)\nplt.figure(figsize=(8, 4.5))\ny_train[-2 * 24 :].plot(label=\"Actual (train)\")\ny_test[: len(forecast)].plot(label=\"Actual (test)\")\nforecast.plot(label=\"Forecast with\\n90% Prediction interval\", low_quantile=0.05, high_quantile=0.95)\nplt.gca().set_xlabel(\"\")\nplt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f\"{x/1000:,.0f} MWh\"))\nplt.gca().tick_params(axis=\"both\", labelsize=10)\nplt.legend(loc=\"upper right\", title=\"Energy consumption\", title_fontproperties={\"weight\": \"bold\"})\nplt.tight_layout()\n```\n\n\u003c/details\u003e\n\n## Contributing\n\n\u003cdetails\u003e\n\u003csummary\u003ePrerequisites\u003c/summary\u003e\n\n1. [Generate an SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key) and [add the SSH key to your GitHub account](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account).\n1. Configure SSH to automatically load your SSH keys:\n\n    ```sh\n    cat \u003c\u003c EOF \u003e\u003e ~/.ssh/config\n    \n    Host *\n      AddKeysToAgent yes\n      IgnoreUnknown UseKeychain\n      UseKeychain yes\n      ForwardAgent yes\n    EOF\n    ```\n\n1. [Install Docker Desktop](https://www.docker.com/get-started).\n1. [Install VS Code](https://code.visualstudio.com/) and [VS Code's Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers). Alternatively, install [PyCharm](https://www.jetbrains.com/pycharm/download/).\n1. _Optional:_ install a [Nerd Font](https://www.nerdfonts.com/font-downloads) such as [FiraCode Nerd Font](https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/FiraCode) and [configure VS Code](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions) or [PyCharm](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions) to use it.\n\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003eDevelopment environments\u003c/summary\u003e\n\nThe following development environments are supported:\n\n1. ⭐️ _GitHub Codespaces_: click on [Open in GitHub Codespaces](https://github.com/codespaces/new/superlinear-ai/conformal-tights) to start developing in your browser.\n1. ⭐️ _VS Code Dev Container (with container volume)_: click on [Open in Dev Containers](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/superlinear-ai/conformal-tights) to clone this repository in a container volume and create a Dev Container with VS Code.\n1. ⭐️ _uv_: clone this repository and run the following from root of the repository:\n\n    ```sh\n    # Create and install a virtual environment\n    uv sync --python 3.10 --all-extras\n\n    # Activate the virtual environment\n    source .venv/bin/activate\n\n    # Install the pre-commit hooks\n    pre-commit install --install-hooks\n    ```\n\n1. _VS Code Dev Container_: clone this repository, open it with VS Code, and run \u003ckbd\u003eCtrl/⌘\u003c/kbd\u003e + \u003ckbd\u003e⇧\u003c/kbd\u003e + \u003ckbd\u003eP\u003c/kbd\u003e → _Dev Containers: Reopen in Container_.\n1. _PyCharm Dev Container_: clone this repository, open it with PyCharm, [create a Dev Container with Mount Sources](https://www.jetbrains.com/help/pycharm/start-dev-container-inside-ide.html), and [configure an existing Python interpreter](https://www.jetbrains.com/help/pycharm/configuring-python-interpreter.html#widget) at `/opt/venv/bin/python`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eDeveloping\u003c/summary\u003e\n\n- This project follows the [Conventional Commits](https://www.conventionalcommits.org/) standard to automate [Semantic Versioning](https://semver.org/) and [Keep A Changelog](https://keepachangelog.com/) with [Commitizen](https://github.com/commitizen-tools/commitizen).\n- Run `poe` from within the development environment to print a list of [Poe the Poet](https://github.com/nat-n/poethepoet) tasks available to run on this project.\n- Run `uv add {package}` from within the development environment to install a run time dependency and add it to `pyproject.toml` and `uv.lock`. Add `--dev` to install a development dependency.\n- Run `uv sync --upgrade` from within the development environment to upgrade all dependencies to the latest versions allowed by `pyproject.toml`. Add `--only-dev` to upgrade the development dependencies only.\n- Run `cz bump` to bump the package's version, update the `CHANGELOG.md`, and create a git tag. Then push the changes and the git tag with `git push origin main --tags`.\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperlinear-ai%2Fconformal-tights","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuperlinear-ai%2Fconformal-tights","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperlinear-ai%2Fconformal-tights/lists"}