Metadata-Version: 2.4
Name: iso-tollgate
Version: 0.1.0
Summary: Pre-submission safety gate for ISO 20022 payment messages. Catches the gap between schema-valid and network-acceptable before you submit.
Project-URL: Homepage, https://github.com/iso-tollgate/tollgate
Project-URL: Repository, https://github.com/iso-tollgate/tollgate
Project-URL: Issues, https://github.com/iso-tollgate/tollgate/issues
Project-URL: Documentation, https://github.com/iso-tollgate/tollgate/blob/main/docs/usage.md
Author: Arun
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: fedwire,iso20022,pacs.008,payments,swift,validation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.11
Requires-Dist: anthropic>=0.40
Requires-Dist: lxml>=5.0
Requires-Dist: pydantic>=2.0
Requires-Dist: rich>=13.0
Requires-Dist: typer>=0.12
Requires-Dist: xmlschema>=3.0
Provides-Extra: dev
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# tollgate

**Catches ISO 20022 payment messages that pass schema validation and still get rejected by the network — before you find out the hard way.**

[![Tests](https://img.shields.io/badge/tests-163%20passing-brightgreen)](#status) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE) [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](pyproject.toml)

A pacs.008 payment message can be 100% valid XML, pass every XSD check, and still bounce off a real clearing network — because some of the rules that matter live outside the schema entirely. Tollgate catches that gap.

## Quickstart

```bash
git clone https://github.com/iso-tollgate/tollgate.git
cd tollgate
pip install -e .
```

```bash
tollgate validate payment.xml
```

```
1 error(s), 0 warning(s) found in payment.xml:

ERROR charset_violation -- FIToFICstmrCdtTrf/CdtTrfTxInf/Dbtr/Nm
  Contains character(s) outside SWIFT's character set X: 'ü'. This is
  schema-valid XML (ISO 20022 permits full Unicode) but SWIFT's network
  layer restricts allowed characters independently of the schema --
  this will not be caught by XSD validation alone.
```

That's a real example, not a mockup — every command in this README was actually run before being written down. No payment file handy? Generate one:

```bash
tollgate generate --count 1 --rule-id charset_violation --output-dir /tmp/fixtures
tollgate validate /tmp/fixtures/charset_violation_0.xml
```

→ **[Full usage guide](docs/usage.md)** — every command, every flag, the Python library API, batch directory checking, the GitHub Action
→ **[Why this exists](docs/why.md)** — the dated deadline behind it, the AI design philosophy, what was found and fixed during development
→ **[Sources](docs/SOURCES.md)** — every rule traced to a citation

## What it checks

One message type in v1: **pacs.008.001.08**, the FI-to-FI customer credit transfer used across Fedwire, CHIPS, and SWIFT CBPR+.

| Check | Catches |
|---|---|
| Schema validity | Standard XSD structural validation. The floor everything else stands on. |
| SWIFT character set | A character outside SWIFT's allowed set — schema-valid, network-invalid. |
| Address structure | Free-format addresses used where structure is required, or line counts the schema allows but a network's guidelines don't. |
| Truncation signals | A value landing at exactly 35 or 70 characters — old legacy line limits — in a field with a much higher modern limit. Reported as a warning, not a certainty. |
| Network-mandatory gaps | Fields the schema marks optional that a real network requires in practice (e.g. UETR for Fedwire). |

Every rule traces to a primary source — see [`docs/SOURCES.md`](docs/SOURCES.md). No rule ships without one.

## Not a compliance tool

Tollgate is a developer-facing sanity check, not a replacement for SWIFT certification or MyStandards testing. It covers one message type, checks structure and format (not business logic like BIC reachability), and is explicit in [`docs/why.md`](docs/why.md) about every limitation found during development. If it can't catch something, the docs say so.

## Three ways to use it

| | |
|---|---|
| **CLI** | `tollgate validate payment.xml` · `tollgate validate-dir payments/` |
| **Python library** | `from tollgate import check_message, check_file, check_directory` |
| **CI** | `uses: iso-tollgate/tollgate/.github/actions/validate@main` |

Details and examples for all three: [`docs/usage.md`](docs/usage.md).

## Status

166 tests passing (163 deterministic/local + 3 live API tests, all confirmed passing against the real Anthropic API), 0 skipped when an `ANTHROPIC_API_KEY` is set — and 163 passing with the 3 API tests skipping cleanly when it isn't, so the full deterministic suite (every validation rule, the generator, the eval harness, both APIs) needs zero API key to verify.

`--explain` has been live-tested against the real model: it correctly names the violated field and cause, and correctly hedges on warning-severity (heuristic) findings rather than asserting them as certain failures — verified, not assumed.

Not yet on PyPI or Homebrew — clone-and-install is the path for now. A Homebrew tap is scaffolded in [`homebrew-tollgate/`](https://github.com/iso-tollgate/homebrew-tollgate) for once a tagged release exists.

## License

Apache 2.0. See [`LICENSE`](LICENSE).
