Metadata-Version: 2.4
Name: regcite
Version: 0.1.0
Summary: Static analysis for UK financial regulatory citations in Python code.
Project-URL: Homepage, https://github.com/OpenAfterHours/regcite
Project-URL: Repository, https://github.com/OpenAfterHours/regcite.git
Project-URL: Issues, https://github.com/OpenAfterHours/regcite/issues
Project-URL: Changelog, https://github.com/OpenAfterHours/regcite/blob/master/CHANGELOG.md
Author: OpenAfterHours
Maintainer: OpenAfterHours
License: Apache-2.0
License-File: LICENSE
Keywords: audit,banking,basel,citations,compliance,crr,pra,regulation,static-analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: polars>=1.0.0
Requires-Dist: typer>=0.12.0
Provides-Extra: dev
Requires-Dist: mkdocs-material>=9.5.0; extra == 'dev'
Requires-Dist: mkdocs>=1.6.0; extra == 'dev'
Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.3.0; extra == 'dev'
Requires-Dist: ty; extra == 'dev'
Description-Content-Type: text/markdown

# regcite

> [!IMPORTANT]
> *This package is still in development and is not production ready.*

Static analysis for UK financial regulatory citations in Python code.

`regcite` lets you annotate Python functions with citations to UK
financial regulation — CRR, the PRA Rulebook, PRA Policy Statements,
PRA Supervisory Statements — and then check those citations against a
bundled, versioned snapshot of the rulebook. The intent is to make the
mapping from compliance code to the regulation it implements *executable*:
runs in CI, lives next to the code, and breaks the build when it drifts.

## Why this exists

Regulatory engineering teams in UK banks need an auditable trail from
every formula in their RWA / capital code back to a specific article of
the CRR or rule in the PRA Rulebook. Today that trail is produced by
hand in Word documents that drift the moment anyone changes the code.
`regcite` puts the mapping where the code is, checks it on every commit,
and gives reviewers, auditors, and the PRA something verifiable to look
at instead of a stale spreadsheet.

The first real user is
[`OpenAfterHours/rwa_calculator`](https://github.com/OpenAfterHours/rwa_calculator)
— a UK CRR / Basel 3.1 credit-risk RWA library whose formulas need to
trace back to specific articles. If you're building something similar,
`regcite` is for you.

## Install

```bash
uv add regcite
# or
pip install regcite
```

Python 3.11+.

## Quickstart

Decorate a function with the regulation it implements:

```python
from regcite import cites


@cites("CRR Art. 153(1)(a)")
def corporate_rw(pd: float, lgd: float, maturity: float) -> float:
    """Risk-weight under the IRB approach for corporates."""
    ...
```

Add a `[tool.regcite]` table to your `pyproject.toml`:

```toml
[tool.regcite]
rulebook_version = "2024-07-09"
instruments = ["CRR", "PRA_RULEBOOK", "PS", "SS"]
source_paths = ["src"]
```

Run the checker:

```bash
$ uv run regcite check
regcite: checked 47 citation(s); no issues found.
```

If a citation fails to parse or points at something the bundled index
doesn't know about, `regcite check` exits non-zero and prints a line
per finding with file, line number, and reason — suitable for CI:

```
src/myproj/sa.py:31: sovereign_rw: unknown_article: citation 'CRR Art. 999' points to CRR Article 999, which is not in the bundled rulebook index
regcite: 1 failing finding(s), 0 unresolved, out of 12 resolved citation(s).
```

`@cites` is a no-op at runtime — it attaches the parsed citation to the
function as `__regcite__` and returns the function unchanged. No
wrapping, no overhead, nothing to debug.

## Citation grammar

The parser accepts canonical UK regulatory citation strings. The shape
that comes out the other side is a frozen `Citation` dataclass; see
`regcite.Citation` for the field list.

| Input                              | Meaning                                                  |
| ---------------------------------- | -------------------------------------------------------- |
| `CRR Art. 153`                     | Whole article                                            |
| `CRR Article 153`                  | (alternate spelling)                                     |
| `CRR Art. 153(1)`                  | Paragraph                                                |
| `CRR Art. 153(1)(a)`               | Point                                                    |
| `CRR Art. 153(1)(a)(ii)`           | Sub-point                                                |
| `CRR Art. 4(1)(75)`                | Numeric point (CRR definitions)                          |
| `PRA Rulebook, Credit Risk, 3.2`   | Rulebook section                                         |
| `PS9/24`                           | PRA Policy Statement, whole document                     |
| `SS1/23, paragraph 2.5`            | Supervisory Statement with paragraph reference           |
| `Delegated Regulation 2018/171 Art. 3` | UK on-shored EU Delegated Regulation                 |

The keyword for an article accepts `Art`, `Art.`, `Article`, or `article`
in any case. Whitespace is normalised. Anything that doesn't parse is a
`CitationParseError`, which `regcite check` reports with the offending
input — these are code-review events, not silent skips.

## Configuration reference

```toml
[tool.regcite]
# Snapshot of the rulebook to pin to. Decorators that omit `version=`
# inherit this pin. ISO-8601 date.
rulebook_version = "2024-07-09"

# Citation instruments allowed in this project. A citation whose
# instrument is not in this list is reported by `regcite check`.
instruments = ["CRR", "PRA_RULEBOOK", "PS", "SS", "DELEGATED_REG"]

# Directories to walk when running `regcite check` with no arguments.
source_paths = ["src"]
```

## Public API

```python
from regcite import (
    Citation,            # frozen dataclass: instrument, article, paragraph, ...
    parse_citation,      # str -> Citation, raises CitationParseError
    CitationParseError,
    cites,               # the @cites decorator
)
```

Everything else (`regcite.ast_walker`, `regcite.index`, `regcite.checks`,
`regcite.cli`) is internal and may change between releases.

## Roadmap

`regcite` v0.1 is intentionally a narrow vertical slice: get the
citation grammar right against real usage in `rwa_calculator`, ship the
decorator and CLI, then expand.

| Version | Adds                                                                          |
| ------- | ----------------------------------------------------------------------------- |
| v0.1    | Citation grammar, `@cites`, `regcite check`, bundled CRR index               |
| v0.2    | `regcite matrix` (traceability matrix), `regcite stale` (rulebook diff)       |
| v0.3+   | Automated scraping of legislation.gov.uk + the PRA Rulebook                    |

If you have feedback on the citation grammar specifically, please open
an issue — the grammar is the foundation, and getting it wrong now is
much cheaper to fix than getting it wrong later.

## Licence

Apache 2.0. See `LICENSE`.
