Skip to content

Latest commit

 

History

59 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI Arbitration Platform — Python Edition

Automated contract arbitration backed by PostgreSQL, LangChain AI agents, and Ethereum escrow.


Table of Contents

  1. What This Is
  2. How It Works — The Full Lifecycle
  3. Architecture
  4. Prerequisites
  5. Installation & Setup
  6. Running the Server
  7. Using the Platform — Step by Step
  8. API Reference
  9. Environment Variables
  10. Status Model
  11. Financial Model
  12. Project Structure
  13. Production Deployment Notes

What This Is

The AI Arbitration Platform is a smart-contract-style legal arbitration system. Two parties — a Seller (provider) and a Buyer (payer) — enter a binding contract. The Buyer deposits ETH into escrow. If they cannot resolve a dispute themselves, a two-stage AI system (Magistrate Judge + Final Judge) investigates the case and issues a legally binding award. Funds are distributed automatically on-chain after a 7-day objection window.

This repository is a Python/FastAPI implementation that mirrors the logic of the original n8n workflows exactly, replacing Google Sheets with PostgreSQL and Google Drive with local file storage.


How It Works — The Full Lifecycle

┌─────────────────────────────────────────────────────────────────────┐
│                        ARBITRATION LIFECYCLE                        │
├──────────┬──────────────────────────────────────────────────────────┤
│ Phase 1  │ Contract submitted → Case ID generated → Emails sent     │
│ Phase 2  │ Both parties accept contract + register ETH wallets      │
│ Phase 3  │ Buyer deposits escrow to on-chain wallet → Verified      │
│ Phase 4  │ Seller requests payment OR Buyer requests refund         │
│ Phase 5  │ Opposing party disputes → Evidence window opens (7 days) │
│ Phase 6  │ AI Magistrate investigates → AI Final Judge rules        │
│ Phase 7  │ 7-day objection window → Award distributed on-chain      │
└──────────┴──────────────────────────────────────────────────────────┘

Each phase maps to one of the five workflow modules:

Module Phase n8n Equivalent
initialization.py 1–2 Initialization.json
transactions.py 3–4 Transactions.json
prosecution.py 4–5 Prosecution.json
adjudication.py 6 Adjudication.json
objection.py 7 Objection.json
exceptions.py Global Exceptions.json

Architecture

┌─────────────────────────────────────────────────────────┐
│                     FastAPI Application                 │
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐               │
│  │  Routes  │  │ Templates│  │  Static  │               │
│  │ (6 mods) │  │ (Jinja2) │  │  (CSS)   │               │
│  └────┬─────┘  └──────────┘  └──────────┘               │
│       │                                                 │
│  ┌────▼──────────────────────────────────────────┐      │
│  │           SQLAlchemy ORM (models.py)          │      │
│  └────┬──────────────────────────────────────────┘      │
│       │                                                 │
└───────┼─────────────────────────────────────────────────┘
        │
┌───────▼─────────────────────────────────────────────────┐
│         PostgreSQL + pgvector Database (Docker :5433)   │
│  ┌─────────────────────────┐  ┌──────────────────────┐  │
│  │   Case & Ledger Tables  │  │   legal_knowledge    │  │
│  │  (cases, messages, etc) │  │ (pgvector HNSW + FTS)│  │
│  └─────────────────────────┘  └──────────────────────┘  │
└─────────────────────────────────────────────────────────┘

Key design choices:

  • PostgreSQL + pgvector via Docker acts as the immutable case ledger and high-performance vector database (VECTOR(384) with HNSW cosine index + GIN English full-text search index).
  • Legal ETL Ingestion Pipeline (legal_etl.py): Ingests authoritative statutes (e.g., UCC), commercial regulations, and dispute precedents with statutory section tagging (§, ARTICLE, SECTION), semantic embeddings, and non-destructive versioning (is_current = FALSE deprecation).
  • Agentic RAG Adjudication: The Magistrate Judge runs as an AI RAG agent equipped with a 5-tool toolbelt:
    1. search_legal_authorities — Hybrid search using Reciprocal Rank Fusion (RRF) combining pgvector cosine similarity and PostgreSQL full-text search.
    2. fetch_legal_authority — Context expansion to pull the full sequential text for a statute or case.
    3. read_evidence_file — Directly extracts text and tables from PDF/TXT party evidence.
    4. calculator — Evaluates deterministic Wei mathematical awards and damage splits.
    5. external_verification — Verifies public URLs, tracking numbers, or pricing benchmarks.
  • Two-Stage Multi-Provider Resilience: Heavy multimodal model for Magistrate investigation (gpt-4o, gemini-1.5-pro) and fast model for Final Judge ruling (gpt-4o-mini, gemini-1.5-flash, deepseek-chat) with automatic with_fallbacks().
  • Zero-Trust Financial Enforcement: Payouts are mathematically validated (buyer_award + seller_award == escrow_balance) before recording to the database.
  • Gmail IMAP Ingestion: A built-in IMAP client automatically polls for email replies, extracts Case IDs, hashes attachments, and saves them to the case ledger.
  • APScheduler: Manages automated cron jobs for timeouts, evidence window expirations, and Gmail polling.
  • Blockchain verified: Actual Etherscan API validation replaces mock deposits.
  • Email is sent via SMTP: Powered by email_service.py using standard SMTP credentials.

Prerequisites

Before you start, make sure you have:

Tool Version Purpose
Python 3.9+ Runtime
Docker Desktop Latest PostgreSQL container
Git Any Cloning the repo
OpenAI API Key AI adjudication (Phase 6 only)

Docker Desktop must be running before you start the database.


Installation & Setup

Step 1 — Clone the repository

git clone https://github.com/just-bots/ai-arbitration-python.git
cd ai-arbitration-python

Step 2 — Create your environment file

cp .env.example .env

Open .env and fill in your values. At minimum, set OPENAI_API_KEY for AI adjudication to work. Everything else has safe defaults for local development.

# Minimum required for local dev:
OPENAI_API_KEY=sk-...your-key-here...

# Optional — defaults are fine for local testing:
BASE_URL=http://localhost:8000/
ADMIN_EMAIL=admin@example.com
ESCROW_WALLET=0x0000000000000000000000000000000000000000
PROCESSING_FEE=1000000000000000        # 0.001 ETH in Wei
DATABASE_URL=postgresql://postgres:password@localhost:5433/arbitration

See Environment Variables for the full list.

Step 3 — Start the database (with pgvector)

docker-compose up -d

This starts a pgvector/pgvector:pg15 container named arbitration-db on port 5433.
To verify it's running:

docker ps
# You should see: arbitration-db   pgvector/pgvector:pg15   Up ...   0.0.0.0:5433->5432/tcp

Step 4 — Install Python dependencies

pip install -r requirements.txt

If you're on macOS and get a psycopg2 error, try: pip install psycopg2-binary

Step 5 — Initialize Schema & Ingest Legal Knowledge

  1. Create the case ledger tables:
python create_tables.py
  1. Ingest governing commercial codes, UCC statutes, and dispute precedents into pgvector:
python legal_etl.py legal_sources.json

Expected output:

[legal-etl] Ingesting UCC-ARTICLE-2-SALES...
[legal-etl] Generating embeddings for 6 chunks...
[legal-etl] Successfully inserted 6 chunks for: UCC-ARTICLE-2-SALES

Step 6 — (Optional) Inspect the database

Connect with any SQL client using:

Setting Value
Host 127.0.0.1
Port 5433
Database arbitration
Username postgres
Password password

Recommended clients: TablePlus, DBeaver, pgAdmin


Running the Server

python -m uvicorn main:app --reload --port 8000

The server is now live at http://localhost:8000

URL Description
http://localhost:8000/ Case creation form (start here)
http://localhost:8000/docs Auto-generated Swagger API docs
http://localhost:8000/redoc ReDoc API docs

The --reload flag makes the server automatically restart when you edit any Python file.


Using the Platform — Step by Step

Important: In local development, emails are not actually sent.
All email links are printed to the terminal/console where the server is running.
Watch the terminal output — every link you need for the next step will appear there.


Phase 1 — Case Creation

Who does this: The platform operator or one of the parties

  1. Open http://localhost:8000/
  2. Fill in the registration form:
    • Seller name + email — the service provider (e.g., contractor, freelancer, landlord)
    • Buyer name + email — the payer (e.g., client, employer, renter)
    • Seller ETH wallet — Ethereum address for receiving awards
    • Buyer ETH wallet — Ethereum address for receiving refunds
    • Required Escrow Fund (ETH) — the amount the Buyer must deposit (e.g., 0.5)
    • Contract file — upload the PDF of the contract
  3. Click Submit

What happens:

  • A unique Case ID is generated (e.g., CASE-3F7A2B1C)
  • Party tokens are created for secure link authentication
  • The case is saved to the database with status = PENDING
  • Escrow fund is stored in Wei (ETH × 10¹⁸)
  • Two simulated emails are printed to the terminal:
    --- EMAIL SIMULATION ---
    To: seller@example.com
    Subject: Action Required: Contract Registered (CASE-3F7A2B1C)
    Link: http://localhost:8000/response?caseId=CASE-3F7A2B1C&party=Seller&action=accept&token=...
    Wallet: http://localhost:8000/wallet?caseId=CASE-3F7A2B1C&party=Seller&token=...
    
    To: buyer@example.com
    Subject: Action Required: Contract Registered (CASE-3F7A2B1C)
    Link: http://localhost:8000/response?caseId=CASE-3F7A2B1C&party=Buyer&action=accept&token=...
    

Phase 2 — Contract Acceptance & Wallet Registration

Who does this: Both Seller and Buyer independently

2a — Accept the contract

Each party uses their unique link from the terminal:

http://localhost:8000/response?caseId=CASE-...&party=Seller&action=accept&token=...
http://localhost:8000/response?caseId=CASE-...&party=Buyer&action=accept&token=...

To decline, change action=accept to action=decline in the URL.

What happens:

  • The party's response is recorded in the database
  • When both parties accept → status = SIGNED
  • If either party declines → status = DECLINED

2b — Register a wallet (if not provided at creation)

Parties can submit or update their Ethereum wallet address:

http://localhost:8000/wallet?caseId=CASE-...&party=Seller&token=...
http://localhost:8000/wallet?caseId=CASE-...&party=Buyer&token=...

The address is validated against the Ethereum format (0x + 40 hex characters).


Phase 3 — Escrow Deposit

Who does this: The Buyer

In production, the Buyer sends ETH to the ESCROW_WALLET address with the Case ID encoded in the transaction data field. In local development, this is mocked.

To simulate a deposit locally:

http://localhost:8000/transactions/verify?caseId=CASE-...

What happens:

  • The system checks if the deposited amount meets Escrow Fund + Processing Fee
  • If sufficient: deposited_fund is recorded, status stays SIGNED
  • If the deposit exceeds the required amount, Excess Funds are detected. The buyer receives dedicated links to either Withdraw Excess or Tip the Seller.
  • The terminal prints the next-step links for both parties:
    --- EMAIL SIMULATION: FUNDING CONFIRMED ---
    To: seller@example.com
    Action: Release Payment -> http://localhost:8000/transactions/action?caseId=...&token=...&actionType=release_payment
    
    To: buyer@example.com
    Action: Request Refund -> http://localhost:8000/transactions/action?caseId=...&token=...&actionType=request_refund
    

Phase 4 — Payment or Refund Request

Who does this: Either party, depending on the outcome

Once funded, the two parties have a chance to settle without a dispute:

Option A — Buyer releases payment to Seller

The Buyer uses their token link with actionType=release_payment:

http://localhost:8000/transactions/action?caseId=CASE-...&token={buyer_token}&actionType=release_payment

What happens:

  • The remaining escrow balance is calculated
  • payment_to_seller is incremented by the remittance amount
  • If the full escrow is paid: status = CLOSED
  • A simulated blockchain transfer is logged to the terminal

Option B — Buyer requests a refund (initiates dispute)

http://localhost:8000/transactions/action?caseId=CASE-...&token={buyer_token}&actionType=request_refund

What happens:

  • status = DISPUTED
  • dispute_time and refund_request_time are both recorded
  • A Dispute message is logged in the messages table
  • This triggers the 7-day evidence window (Phase 5)

Phase 5 — Dispute & Evidence Collection

Who does this: Both parties submit arguments and supporting files

5a — Submit evidence

Both Seller and Buyer can submit arguments and evidence files:

http://localhost:8000/prosecution/evidence?caseId=CASE-...&token={party_token}

On this form:

  • Write your argument in the text area
  • Attach supporting files (PDFs, images, documents)
  • Click Submit Evidence

What happens:

  • The argument is saved as a Message record with label = Dispute
  • Each file is SHA-256 hashed, renamed securely, and saved to storage/evidence/
  • File metadata is recorded in the files table linked to the message

5b — Escalate to adjudication

When the 7-day evidence window closes (or you want to manually escalate for testing):

# POST request to escalate
curl -X POST http://localhost:8000/prosecution/escalate \
  -d "caseId=CASE-..."

Or visit /docs and use the Swagger UI.

What happens:

  • status = DISPUTED (confirming ready for AI pickup)
  • dispute_time is recorded (if not already set)
  • The AI adjudication scheduler will pick this up in Phase 6

Phase 6 — AI Adjudication

Who does this: The AI (triggered by the operator / admin)

⚠️ Requires OPENAI_API_KEY to be set in .env

The AI adjudication is a two-stage process:

Stage 1: Magistrate Judge (RAG Agent)

Investigates the case impartially as a tool-calling RAG agent equipped with a 5-tool toolbelt:

  • search_legal_authorities — RRF hybrid search (pgvector cosine distance + PostgreSQL tsvector lexical match)
  • fetch_legal_authority — Context expansion to inspect complete statutory articles and exceptions
  • read_evidence_file — Reads party-submitted PDF and text files
  • calculator — Deterministic mathematical award calculations
  • external_verification — Fetches URLs for tracking or pricing verification

Produces a structured MagistrateReport with:

  • Neutral summary and timeline
  • Verified facts (each citing specific evidence)
  • Contradictions and unsubstantiated claims
  • Applicable governing legal authorities (applicable_legal_authorities)
  • Recommended payout split in Wei (recommended_buyer_payout, recommended_seller_payout)

Stage 2: Final Judge

Reviews the Magistrate's report and issues a legally binding ruling with:

  • Final decision text
  • buyer_award and seller_award in Wei
  • Detailed rationale
  • Confidence score (0.0 – 1.0)

Math validation: The system enforces buyer_award + seller_award == escrow_balance exactly. If the AI fails this check, the admin is alerted and the ruling is rejected.

How to trigger adjudication:

curl -X POST http://localhost:8000/adjudication/run \
  -d "caseId=CASE-..."

Or use the Swagger UI at http://localhost:8000/docsPOST /adjudication/run

What happens:

  1. Case is locked immediately: status = PROCESSING, adjudication_time recorded
  2. All messages and files are loaded from the database
  3. A structured case packet is built and sent to the Magistrate LLM
  4. Magistrate report is validated (math + format)
  5. Final Judge receives the Magistrate report and issues a ruling
  6. Ruling is validated: buyer_award + seller_award must equal escrow_balance
  7. On success:
    • status = DECIDED
    • determination_time, decision, seller_award, buyer_award stored
    • Simulated determination emails printed to terminal with 7-day appeal link

What the terminal prints:

--- EMAIL SIMULATION: FINAL DETERMINATION ---
To: seller@example.com | To: buyer@example.com
Subject: Final Determination for Case CASE-...
Decision: [AI ruling text]
Seller Award: X ETH | Buyer Award: Y ETH
Appeal Link (valid 7 days): http://localhost:8000/objection/appeal?caseId=...&token=...

Phase 7 — Objection & Award Distribution

Who does this: Either party (objection), then the Admin (review), then the system (distribution)

7a — File a procedural objection (optional)

Either party has 7 days from determination_time to file a procedural objection:

http://localhost:8000/objection/appeal?caseId=CASE-...&token={party_token}

On the form:

  • Describe the procedural or logical error in the ruling
  • Check "I confirm this objection contains no new argument"
  • Click Submit

⚠️ Objections are limited to procedural/logical errors. No new evidence or arguments are permitted.

What happens:

  • Objection text is saved as an APPEAL message
  • appeal_time is recorded
  • A simulated admin alert is printed to the terminal with the review portal link

7b — Admin HITL Review (if objection filed)

The admin reviews the objection at:

http://localhost:8000/objection/review?caseId=CASE-...

The admin sees the full case, the AI ruling, and the objection text.
The admin selects one of two decisions:

Decision Action n8n equivalent
Uphold Original ruling stands; case returns to DECIDED for distribution Uphold Determination
Reverse Ruling wiped; case returns to DISPUTED for re-adjudication Revert Determination

Submit via:

# Uphold
curl -X POST http://localhost:8000/objection/review \
  -d "caseId=CASE-...&action=uphold"

# Reverse
curl -X POST http://localhost:8000/objection/review \
  -d "caseId=CASE-...&action=reverse"

7c — Award Distribution

In n8n, the Objection.json workflow runs on a hourly schedule and automatically distributes ETH after 7 days. In this Python implementation, distribution is triggered via the review endpoint (uphold path) or can be called directly.

When distribution runs:

  • seller_award ETH is transferred to seller_wallet
  • buyer_award ETH is transferred to buyer_wallet
  • status = CLOSED
  • Both parties receive a confirmation email with the Etherscan transaction link

In local dev, blockchain transfers are mocked (logged to terminal). In production, set PRIVATE_KEY and TATUM_API_KEY for real on-chain transfers.


API Reference

All endpoints are also browsable at http://localhost:8000/docs

Initialization

Method Endpoint Auth Description
GET / None Case creation form
POST /create-case None Submit new contract
GET /success/{case_id} None Case created confirmation
GET /response token Accept or decline contract
GET /wallet token Wallet submission form
POST /wallet-submit token Save Ethereum wallet address

Transactions

Method Endpoint Auth Description
GET /transactions/verify caseId Verify escrow deposit (mock)
GET /transactions/action token Release payment or request refund

/transactions/action query parameters:

Parameter Values Who
caseId Case ID string
token Party's unique token
actionType release_payment Buyer only
actionType request_refund Buyer only

Prosecution

Method Endpoint Auth Description
GET /prosecution/evidence token Evidence submission form
POST /prosecution/evidence token Submit argument + files
POST /prosecution/escalate None Escalate case to DISPUTED

Adjudication

Method Endpoint Auth Description
POST /adjudication/run None Run two-stage AI adjudication

Objection

Method Endpoint Auth Description
GET /objection/appeal token Procedural objection form
POST /objection/appeal token Submit objection
GET /objection/review Admin HITL review dashboard
POST /objection/review Admin Uphold or reverse ruling

Environment Variables

Copy .env.example to .env and configure these variables:

Variable Required Default Description
DATABASE_URL Yes postgresql://postgres:password@localhost:5433/arbitration PostgreSQL connection string
BASE_URL Yes http://localhost:8000/ Public base URL for tokenized email links
ADMIN_EMAIL Yes admin@example.com Recipient of all system error alerts
ESCROW_WALLET Yes 0x000...000 Ethereum wallet receiving escrow deposits
PRIVATE_KEY Prod only Private key for signing payout transactions (never commit)
PROCESSING_FEE Yes 1000000000000000 Platform fee in Wei (default = 0.001 ETH)
OPENAI_API_KEY Phase 6 OpenAI API key for LangChain AI agents
ETHERSCAN_API_KEY Prod only For real deposit verification
TATUM_API_KEY Prod only For broadcasting ETH payout transactions
SMTP_HOST Prod only SMTP server for email fallback
SMTP_PORT Prod only 587 SMTP port
SMTP_USER Prod only SMTP login email
SMTP_PASS Prod only SMTP password

⚠️ PRIVATE_KEY controls the escrow wallet. Store it in a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.) — never in .env files committed to version control.


Status Model

Status Meaning Next transition
PENDING Case created; awaiting both signatures SIGNED or DECLINED
SIGNED Both accepted; awaiting escrow deposit DISPUTED
DECLINED At least one party declined Terminal
DISPUTED Dispute filed; evidence window open PROCESSING
PROCESSING AI adjudication in progress (case locked) DECIDED
DECIDED AI ruling issued; 7-day appeal window CLOSED or → DISPUTED
CLOSED Funds distributed; case complete Terminal

Financial Model

All monetary values are stored as Wei integers in Numeric(38, 0) columns.

1 ETH = 1,000,000,000,000,000,000 Wei  (10¹⁸)

Escrow balance formula:

escrow_balance = max(0, Escrow Fund − Payment to Seller − Refund to Buyer)

Liquid balance formula (available funds in the deposit pot):

liquid_balance = Deposited Fund − Fee − Tip to Seller − Buyer Withdrawal
               − Payment to Seller − Refund to Buyer

AI award validation (strictly enforced):

buyer_award + seller_award == escrow_balance   ← must be exact
buyer_award  >= 0
seller_award >= 0

Project Structure

ai-arbitration-python/
│
├── main.py                    # FastAPI app entry point
├── models.py                  # SQLAlchemy ORM models (Case, Message, File)
├── database.py                # DB session factory
├── create_tables.py           # One-time schema initializer
├── legal_etl.py               # Legal knowledge ETL pipeline for pgvector
├── legal_sources.json         # Authoritative legal sources manifest
├── data/
│   └── legal_docs/            # Local statutory and arbitration markdown sources
├── docker-compose.yml         # PostgreSQL + pgvector container
├── requirements.txt           # Python dependencies
├── .env.example               # Environment variable template
│
├── routers/
│   ├── initialization.py      # Phase 1–2: Case creation, signatures, wallets
│   ├── transactions.py        # Phase 3–4: Deposit verification, payments
│   ├── prosecution.py         # Phase 4–5: Evidence upload, dispute escalation
│   ├── adjudication.py        # Phase 6:   AI Magistrate + Final Judge
│   ├── objection.py           # Phase 7:   Appeals, HITL review, distribution
│   └── exceptions.py          # Global:    Error handler, admin alerts
│
├── templates/                 # Jinja2 HTML templates
│   ├── layout.html
│   ├── create_case.html
│   ├── success.html
│   ├── response_status.html
│   ├── wallet_form.html
│   ├── deposit_status.html
│   ├── transaction_action.html
│   ├── evidence_form.html
│   ├── evidence_success.html
│   ├── adjudication_result.html
│   ├── objection_form.html
│   └── objection_review.html
│
├── static/
│   └── css/style.css          # Platform stylesheet
│
├── storage/
│   └── evidence/              # Uploaded evidence files (SHA-256 hashed)
│
├── test_critical.py             # Escrow clamping and financial invariant tests
├── test_legal_rag.py            # Legal RAG hybrid search & ETL unit tests
├── test_initialization.py       # Security test suite for case creation
├── test_transactions.py         # Security test suite for financial logic
├── test_prosecution.py          # Security test suite for evidence flows
└── uploads/                   # Contract PDF uploads

---

## Security & Validation (Zero-Trust Model)

This implementation has undergone a comprehensive zero-trust security audit to harden the arbitration pipeline against manipulation and denial-of-service (DoS) attacks:

- **Strict File Upload Validation**: Case creation and evidence uploads enforce strict 10MB limits via chunked stream tracking (preventing `Content-Length` bypass DoS attacks) and restrict uploads to safe MIME types (PDF, TXT, DOC). Filenames are sanitized against path traversal (`os.path.basename`).
- **Mathematical Clamping**: Escrow funds must be strictly positive at creation. All payouts and refunds are dynamically clamped to `min(requested_amount, available_escrow)` to eliminate integer overflow or fund leakage exploits.
- **Accounting Isolation**: Tip and withdrawal requests are completely isolated from general payment requests, preventing "Ghost Tip" attacks where a malicious party could artificially drain the opponent's excess ledger balance without transferring actual ETH.
- **State Machine Enforcement**: Endpoints like `/dispute` and `/escalate` enforce strict pre-requisite state checks (e.g., must be `EFFECTIVE` or `SIGNED`), preventing attackers from resurrecting `CLOSED` cases or escalating unfunded cases to exhaust AI API quotas.
- **Complete Test Coverage**: Security logic is continuously verified by isolated `pytest` suites (`test_initialization.py`, `test_transactions.py`, `test_prosecution.py`), preventing regressions.

Production Deployment Notes

1. Real email sending

Replace the print() statements in each router with an SMTP client or transactional email provider (SendGrid, Mailgun, Postmark).

Note: The global exception handler (exceptions.py) is already fully wired to send admin SMTP alerts for unhandled errors and AI adjudication math/schema validation failures, ensuring a zero-trust alert system.

2. Real blockchain integration

  • Set ETHERSCAN_API_KEY to enable real deposit scanning via the Etherscan API
  • Set TATUM_API_KEY + PRIVATE_KEY to enable real ETH payout broadcasting via Tatum v3

3. Real file storage

Replace storage/evidence/ with Google Drive, AWS S3, or equivalent. Update the file upload/download logic in prosecution.py and adjudication.py.

4. Scheduled adjudication

The n8n workflows run adjudication on a 12-hour schedule and distribution on an hourly schedule. In production, set up cron jobs or a task queue (Celery, APScheduler) to call:

  • POST /adjudication/run every 12 hours (picks up DISPUTED cases ≥ 7 days old)
  • Award distribution logic every hour (picks up DECIDED cases ≥ 7 days old)

5. Security hardening

  • Serve over HTTPS (use a reverse proxy: Nginx, Caddy, or Traefik)
  • Move PRIVATE_KEY to a secrets manager
  • Rate-limit token-authenticated endpoints
  • Add authentication to /adjudication/run and /objection/review

6. AI model configuration

The adjudication router is already configured with separated models for efficiency:

  • Magistrate Judgegpt-4o (multimodal, capable of reading evidence) with fallbacks to gemini-1.5-pro and gpt-4o-mini.
  • Final Judgegpt-4o-mini (text-only, fast, efficient JSON output) with fallbacks to deepseek-chat, gemini-1.5-flash, and gpt-3.5-turbo.

Update the model initialization in adjudication.py to use your preferred provider.

About

AI Arbitration Platform with Python & LangChain

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages