Skip to main content

sorry

sorry marks unfinished Python code as structured debt that CI can find and refuse to ship.

It is not a productivity aid. It is a nagging conscience for the build pipeline. Standard TODO comments are a graveyard of good intentions. sorry makes them load-bearing: structured metadata, an AST scanner, and a calendar.

Install

pip install pysorry

The distribution is pysorry. The import is sorry.

Mark the hole

Two markers. Use whichever fits the shape of the unfinished thing.

Runtime marker

from sorry import sorry


def reconcile_authority(step):
    return sorry(
        "corrective monotonicity not discharged",
        issue="AG-27",
        owner="agent-gov",
        expires="2026-06-01",
    )

sorry(...) always raises UnprovenObligation (an AssertionError subclass). The return type is NoReturn, so type checkers treat anything after it as unreachable.

Decorator marker

from sorry import unfinished


@unfinished(
    "corrective monotonicity not discharged",
    issue="AG-27",
    expires="2026-06-01",
)
def corrective_never_mints_authority(step) -> bool:
    ...

The decorator runs cleanly at import time. The wrapped function raises UnprovenObligation when called.

Scan the hole

sorry list src tests

Lists every obligation. Always exits 0.

sorry check src tests

Exits 1 if any obligation exists. No warn-only mode. No per-path policy file. The tool is binary by design: either the debt is discharged, or the build is broken.

Metadata

All fields are optional except the reason. All values must be string literals when scanned — non-literal metadata is reported as invalid.

field meaning
reason what is unfinished
issue tracker ID or URL
owner who is responsible
expires ISO date YYYY-MM-DD; valid through that date
basis informal justification or reference

Status

Each obligation lands in one of three buckets:

  • OPEN — unresolved, not yet expired
  • EXPIRED — today > expires
  • INVALID — non-literal metadata, malformed expires, missing reason, etc.

sorry check fails on any non-empty bucket. Expired and invalid are visually separated in output, but they fail the same gate.

Scanner limitations

The V0 scanner is import-aware but not scope-aware. It tracks from sorry import … and import sorry [as …] at the module level, but it does not model lexical scope. Two consequences:

  • A function-local import (def f(): from sorry import sorry as s) leaks its alias to the rest of the module — calls to s(...) in sibling functions will be reported as obligations.
  • A parameter or local variable named sorry (or matching an alias) shadows the import at runtime, but the scanner will still flag calls to it.

In practice this means: keep sorry imports at the top of the file and don't shadow them with locals. Scope-aware resolution may land in a later release; until then, the limitation is documented and the false-positive shape is predictable.

Non-goals

  • No --warn-only flag.
  • No pyproject.toml policy section.
  • No per-path config.
  • No pytest plugin.
  • No "discharge" subcommand. To discharge an obligation, delete the call.

The tool is meant to stay tiny. If you need governance, build it elsewhere.

License

Licensed under Apache-2.0. See LICENSE and NOTICE.

Metadata

Release files for pysorry 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 pysorry 0.1.0
File Size Uploaded Provenance
pysorry-0.1.0.tar.gz 16.1 kB With provenance Details

Built distribution (wheel)

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

Total release size: 28.2 kB

Release files / pysorry-0.1.0.tar.gz

Download URL pysorry-0.1.0.tar.gz
Size 16.1 kB
Tags Source
SHA-256 checksum
How to use checksums
57fb1bd58d07f136b5034f42fc5c7612490e799e490e4662af8049b0f32a5ae8
BLAKE2b-256 checksum
How to use checksums
bfa48bd647b69231a742d5e4f1188c1885e83b003521abab5704f1ddd6eab4b1
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 1, 2026.

Transparency log

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

Download URL pysorry-0.1.0-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7314b1b65875350e87176e49d3526ff21e417d87856004662b1641700aacfb5d
BLAKE2b-256 checksum
How to use checksums
69ffd5da300524f083d419861918ec62cb80ba75cb9b223e91cdefdfc3f83ce7
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 1, 2026.

Transparency log

Security for pysorry 0.1.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pysorry-0.1.0.tar.gz

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 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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