Skip to main content

Git-backed register for signed contracts: register executed deals, then surface renewals, notice deadlines, and obligations as a searchable portfolio and an .ics calendar. Local-first, stdlib-only.

Project description

contract-vault

Never miss a contract renewal, notice deadline, or obligation. A git-backed register for your signed contracts: register an executed deal, then search the portfolio and surface renewal / notice / payment deadlines as a calendar. Local-first, single-file, stdlib-only — no DB, no daemon, no SaaS.

obligations is a view over the register, not a separate tool.

  • Stdlib only. Zero runtime dependencies; fully functional with no extras.
  • Git-backed, single file. No DB, no daemon. The vault is a plain git repo.
  • Deterministic. The register, .ics calendar, and reminders work fully with the LLM off and no network.
  • Verify, not trust. Every field carries its source (deterministic | llm | manual | none) and a confidence, surfaced everywhere.

Part of the contract-ops suite — optional. contract-vault stands on its own, but it also composes with the contract-ops CLI suite: it can ingest extract-cli output (so any LLM/parsing need is delegated to that extraction step, never reimplemented here) and shares the suite's agent conventions — sitting at the manage-out end of extract → … → sign → contract-vault. It's the post-signature sibling of template-vault: template-vault stores blank templates, contract-vault stores the signed instances.


Run this

pipx run contract-vault demo     # zero-config: register two sample contracts → renewals calendar
# or, installed:  pip install contract-vault && contract-vault demo

That runs the full ingest → find → due flow on bundled fixtures (no extract-cli, no LLM, no network) and prints a renewals/notice calendar. Point it at your own signed contract with extract contract.pdf | contract-vault ingest -.

Where to go next


Install

pip install contract-vault            # zero dependencies, fully functional

Extraction itself is delegated to extract-cli. contract-vault works without it (piped JSON / .json input), but for one-shot ingestion of real documents install it with the backends you need:

pip install extract-cli               # text / markdown
pip install "extract-cli[docx]"       # + Word
pip install "extract-cli[pdf]"        # + PDF
# convenience extras that pull extract-cli in via contract-vault:
pip install "contract-vault[pdf]"

Requires Python 3.9+.


Quick start

contract-vault init ~/contracts            # create a git-backed vault
contract-vault demo                        # full ingest→find→due flow on bundled fixtures

# Ingest an executed contract (shells out to `extract` if it is on PATH):
contract-vault ingest ~/Downloads/acme-msa.pdf --vault ~/contracts

# ...or compose with extract explicitly (works even if extract is elsewhere):
extract ~/Downloads/acme-msa.pdf --json | contract-vault ingest - --vault ~/contracts

contract-vault list --vault ~/contracts
contract-vault find --auto-renew --value-gt 100000 --vault ~/contracts
contract-vault due --within 90d --format ics --vault ~/contracts > renewals.ics

The --vault flag is optional: contract-vault discovers the vault by walking up from the current directory (like git), or reads $CONTRACT_VAULT_DIR.


The vault model

A vault is a git repository laid out exactly like template-vault, one directory per deal:

~/contracts/
├── .contract-vault.json                       # vault config (kind, schema_version)
├── acme-corporation/
│   └── master-services-agreement/
│       ├── record.json                         # the structured deal record
│       └── source.pdf                          # the executed document (when vaulted)
└── initech-inc/
    └── mutual-non-disclosure-agreement/
        └── record.json

Each record.json conforms to docs/spec/contract-record.schema.json and carries: parties[], effective_date, expiration_date, term{length, auto_renew, notice_period_days, renewal_window}, governing_law, value, status, signed_on, source{path, sha256, format, vaulted}, obligations[]{type, due, description, source, confidence}, provenance{from_extract, extractor_version, ...}, and a field_meta map recording the source + confidence of every field. Re-ingesting the same document (same sha256) is idempotent.


Commands

Command What it does
init [path] Create / initialize an executed-contract vault (a git repo).
ingest <file> Run extract <file> --json (if on PATH) and store + commit the record.
ingest - Read piped extract JSON from stdin (extract f --json | contract-vault ingest -).
list List stored deals.
get <id> / show <id> Print one record (by path, leaf name, or unique prefix).
find / search Query by --counterparty, --governing-law, --currency CCC, --expiring-before DATE, --value-gt N, --auto-renew, or full-text. Pair --currency with --value-gt for currency-aware thresholds.
due / obligations Project upcoming actions. --within 30d|60d|90d, --format ics|json|table, --status open|done|waived|all (default open), --type, --owner. Emits valid RFC 5545 .ics.
obligation <deal> <id> Track an obligation: --status open|done|waived, --owner NAME, --recurrence weekly|monthly|quarterly|semiannual|annual, --reminders 30,7. Completed obligations drop off due; recurring ones expand into occurrences.
stats Portfolio stats: count, total value, expiring soon, by counterparty / governing law.
export Export the register as csv / md / json (--expiring-before, --needs-review). For spreadsheets & reports.
verify Integrity check: source sha256 matches + git tree clean.
review Deterministic worklist of fields that are unidentified / LLM-derived / low-confidence (--threshold; --strict exits 1 for CI). Never calls an LLM.
accept <deal> <field> Mark a reviewed field as human-verified (source=manual), optionally --value to correct it; recomputes the calendar for date/term changes. Bulk via accept --from FILE.
risk / at-risk Renewal exposure: missed notice deadlines (CRITICAL if auto-renewing), imminent notices, and expirations (--within, --strict).
remind The reminder digest: obligations whose reminder window is open right now (honors per-obligation --reminders). For cron/agents (--strict, --format).
config reminders Set corpus-wide default reminder lead-times per type (--type … --set 60,30,7), --show/--clear. Applies to every contract; overridable per obligation.
history <deal> The deal's git history (ingest + each accept).
demo Run the full flow on bundled fixtures (no extract-cli, no LLM).

Global I/O conventions (shared across the suite)

  • --catalog json — print the machine-readable command/flag catalog and exit (the suite discovery contract; agents call this at startup, before any subcommand).
  • --json — machine-readable JSON on stdout (opt-in; default output is human).
  • --why — structured explanation on stderr ([why] <header> + indented lines).
  • -q / --quiet / --silent — suppress non-error output.
  • --no-color — disable ANSI color (also honors NO_COLOR and FORCE_COLOR).
  • -V / --version, -h / --help.
  • Exit codes: 0 ok, 1 failure / findings (e.g. verify mismatch), 2 bad usage.

Composability

# One-shot: extract a PDF and register it.
extract deal.pdf --json | contract-vault ingest -

# Export the next quarter of renewals/notices to any calendar app.
contract-vault due --within 90d --format ics > renewals.ics

# Hand the portfolio to finance/legal as a spreadsheet or a report.
contract-vault export > portfolio.csv
contract-vault export --format md --expiring-before 2027-01-01 > renewals-report.md

# Pipe the machine-readable register into jq.
contract-vault find --expiring-before 2026-01-01 --json | jq '.deals[].id'

# A reminder manifest is just the JSON projection (days_until + suggested lead_days).
contract-vault due --within 365d --format json > reminders.json

--format json (or --json) for due/obligations doubles as a reminder manifest: each row carries days_until and a suggested lead_days. The .ics output is the same data rendered as RFC 5545, with a VALARM per event.


Notifications & reminders

contract-vault has no daemon and sends no notifications itself — it computes deadlines and lead-times deterministically; delivery is your environment's job. There are three ways to actually get notified:

  1. Calendar (zero code). contract-vault due --within 365d --format ics > contracts.ics and subscribe to it. Each event carries VALARMs (TRIGGER:-P30D, …) from the per-obligation --reminders, so your calendar app fires the alerts natively.
  2. Cron / CI gate. Run on a schedule and act on the exit code or piped JSON — e.g. contract-vault remind --strict || mail-me (exit 1 when something is due), or contract-vault risk --within 30d --strict.
  3. An agent (Claude, etc.). The agent polls the CLI and notifies through its own channel. contract-vault is built for this (--catalog json, --json, exit codes, AGENTS.md).

The remind command is the turnkey digest — "what should I be notified about now":

contract-vault remind                 # obligations whose reminder window is open today
contract-vault remind --strict --json # exit 1 + JSON if anything is due (cron/agent loop)

It returns each obligation only while 0 ≤ days_until ≤ its longest reminder lead, honoring obligation <deal> <id> --reminders 30,7. A daily remind --json is exactly the set a notifier should send.

Set lead-times once for the whole corpus (instead of per obligation) with a vault policy:

contract-vault config reminders --type expiration --set 60,30,7   # applies to every contract
contract-vault config reminders --type obligation  --set 14,7

Resolution per obligation: per-obligation --reminders → vault default for its type → vault default catch-all → built-in default.

To run these on a schedule (cron/launchd, a Claude Code remote routine, or CI) and get notified — you pick the cadence and channel — see docs/SCHEDULING.md and the example wrapper scripts/contract-vault-remind.sh.


Shell completion

contract-vault ships a hidden __complete subcommand (matching the template-vault sibling). Register it for bash with:

_contract_vault() {
  COMPREPLY=( $(contract-vault __complete "${COMP_WORDS[@]:1}") )
}
complete -F _contract_vault contract-vault

It completes subcommands, deal ids (for get/show/verify), and query flags/counterparties/governing-laws (for find/search). (extract-cli ships an extract completion <shell> subcommand instead; both styles are valid across the suite — contract-vault uses the hidden-subcommand style.)


LLM (opt-in, delegated) and "verify, not trust"

contract-vault never calls an LLM itself. Identification of clauses and fields — including the LLM fallback for anything the deterministic tiers miss — is the job of extract-cli. ingest --llm simply forwards --llm to the extract step, which runs that LLM tier; shared config is looked up at ~/.config/contract-ops/llm.json first, then ./config/llm.json (see config/llm.json.example). The register / due / .ics paths stay fully deterministic and work with the LLM off.

Every field contract-vault stores carries its source (deterministic | llm | manual | none) and a confidence. review surfaces the ones worth a human look — without calling a model:

contract-vault review                       # unidentified / llm-derived / low-confidence fields
contract-vault review --strict               # exit 1 if anything needs review (CI gate)
contract-vault find --needs-review --json    # which deals need attention
extract deal.pdf --json --llm | contract-vault ingest -   # improve them at extraction time

# After a human checks a contract, record the verdict (-> source=manual, drops out of review):
contract-vault accept acme-corp/msa governing_law --value Delaware
contract-vault accept acme-corp/msa expiration_date --value 2027-01-31   # recomputes the calendar
contract-vault accept acme-corp/msa value            # accept the current value as verified

Interop

The cross-CLI contracts live under docs/spec/ as JSON Schema 2020-12 and are registered in docs/INTEROP.md:


Development

make install      # editable install with dev extras
make test         # full test suite
make typecheck    # mypy --strict
make coverage     # tests under coverage + report
make build        # wheel + sdist
make smoke        # build, install the wheel in a clean venv, run it
make spec-check   # validate fixtures + outputs against docs/spec schemas (offline)

See ARCHITECTURE.md and CONTRIBUTING.md.

License

MIT © DrBaher

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

contract_vault-0.4.2.tar.gz (86.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

contract_vault-0.4.2-py3-none-any.whl (40.1 kB view details)

Uploaded Python 3

File details

Details for the file contract_vault-0.4.2.tar.gz.

File metadata

  • Download URL: contract_vault-0.4.2.tar.gz
  • Upload date:
  • Size: 86.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for contract_vault-0.4.2.tar.gz
Algorithm Hash digest
SHA256 2746cec02b7f698471600c4838b9fa85b331fae0a93c735f18c4d7b9ee69e98d
MD5 1d054a3c0e133715361b909c6b228ac3
BLAKE2b-256 162de30acac1f268dbbc1b60d5782a40128f9d2c344cee06b3a385012b672b49

See more details on using hashes here.

Provenance

The following attestation bundles were made for contract_vault-0.4.2.tar.gz:

Publisher: publish.yml on DrBaher/contract-vault-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file contract_vault-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: contract_vault-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 40.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for contract_vault-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 84db30495db683687979e498eed6683d178b62cb524f53f55c7a54b3773a3566
MD5 cf3dec4de960f8352984a667f6c2a5a1
BLAKE2b-256 99cdc3297acc72ac17d56e90e178b884ab239e5690b474c6f9a2fb6218184f49

See more details on using hashes here.

Provenance

The following attestation bundles were made for contract_vault-0.4.2-py3-none-any.whl:

Publisher: publish.yml on DrBaher/contract-vault-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page