Metadata-Version: 2.4
Name: vaulteq
Version: 1.1.0
Summary: Deterministic double-entry accounting for AI agents
Author-email: FinanceX <dev@financex.example>
License: MIT
Project-URL: Homepage, https://github.com/financex/vaulteq
Project-URL: Repository, https://github.com/financex/vaulteq
Keywords: accounting,ledger,mcp,ai-agents,finance
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Accounting
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == "mcp"

# VaultEq Core — MVP v1.1

> **LLMs orchestrate. VaultEq computes.**

A deterministic, auditable double-entry accounting engine built for AI agent orchestration. This is the foundational 10% of FinanceX — the part you ship before writing another line of design doc.

## What's inside

| File | Purpose |
|------|---------|
| `vaulteq/` | Python package — `engine.py`, `mcp_server.py`, `schema.sql` |
| `pyproject.toml` | Package metadata, dependencies, entry points |
| `demo.py` | Functional demo (imports from installed package) |
| `race_test.py` | Concurrent stress test (imports from installed package) |

## Design decisions

- **Amounts are integer minor units** (`BIGINT`, cents) — never floats, never unconstrained decimals in storage.
- **Audit events are hash-chained** (`prev_event_hash` → SHA-256 of previous event). This proves *deletion* resistance, not just modification resistance.
- **Idempotency is real, not cosmetic:**
  - Same key + same payload → returns cached `PostResponse` (safe retry)
  - Same key + different payload → `DUPLICATE_IDEMPOTENCY_KEY` conflict
  - Check is atomic under `BEGIN IMMEDIATE` with explicit transaction control (`isolation_level=None`)
  - Belt-and-suspenders: `IntegrityError` from the UNIQUE constraint is caught and resolved into proper retry or conflict
- **Error taxonomy is explicit and complete:**

| Code | Meaning |
|------|---------|
| `ORGANIZATION_NOT_FOUND` | Referenced org doesn't exist |
| `INVALID_JOURNAL` | Fewer than 2 lines, or other structural violation |
| `UNBALANCED_JOURNAL` | Debits ≠ credits |
| `ACCOUNT_NOT_FOUND` | Referenced account_code doesn't exist for this org |
| `ACCOUNT_INACTIVE` | Account exists but is closed/inactive |
| `DUPLICATE_IDEMPOTENCY_KEY` | Key already used with a different payload |
| `CURRENCY_MISMATCH` | Line currency has no registered fx_rate to base_currency |
| `PERIOD_CLOSED` | Attempted post to a closed accounting period (deferred) |

## Run it

```bash
python demo.py        # functional demo
python race_test.py   # concurrent idempotency verification
```

No dependencies. Uses Python stdlib + SQLite.

## Why the race test proves what it proves

`race_test.py` uses **separate `sqlite3` connections per thread** (not a shared connection, which would serialize through Python's GIL and mask real cross-connection races) and a **`threading.Barrier`** to force both threads into `post()` at the same instant rather than hoping for a scheduling accident. It asserts the invariant that matters: exactly one journal entry in the database, both threads returning the *same* journal ID, and zero raw `IntegrityError` exceptions leaking to the caller. This is a legitimate concurrency test, not a token one.

## What works now

- [x] Organization & Chart of Accounts management
- [x] Double-entry journal posting with strict balance validation
- [x] **Real idempotency** — safe retries return cached responses, conflicts are explicit
- [x] **Atomic idempotency** under SQLite reserved lock with explicit transaction control
- [x] **Race-safety verified** — concurrent threads with same key produce exactly one journal entry
- [x] Immutable, hash-chained audit trail
- [x] Trial balance query
- [x] Audit chain integrity verification
- [x] Complete error taxonomy with structured JSON responses

## What's intentionally deferred

- [ ] Multi-currency FX rates (MVP enforces base-currency only)
- [ ] Period close / lock
- [ ] Journal reversals
- [ ] HTTP API layer (FastAPI wrapper)
- [ ] Concurrent post safety at scale (SQLite serializes; prod needs row-level locking in Postgres)
- [ ] Postgres migration (swap connection string, schema is compatible)

## The one thing to remember

> This is infrastructure, not a fintech. Your first customer is a developer building an AI agent that needs to post a journal without hallucinating the math.

Ship this. Get feedback. Then build PaymentsX.
