Initial commit on Forgejo
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s

Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
Maxfield Luke 2026-07-29 04:43:40 -04:00
commit af6077b9c3
455 changed files with 78366 additions and 0 deletions

View file

@ -0,0 +1,60 @@
# Credit economy
How credits are minted, spent, and settled - and the rules that keep money out
of the security record's truth machinery.
## Minting (earned, never bought)
Credits are minted only on verification events, by
`Tarakan.Credits.MintWorker`, when a canonical finding's status settles. Fixed
amounts (`Tarakan.Credits.mint_amounts/0`):
| Kind | Amount | Paid to |
| ----------------------- | ------ | ------------------------------------------------------------------ |
| `mint_finding_verified` | 50 | The finder (earliest public occurrence), first settle to `verified` |
| `mint_check_correct` | 10 | Each checker whose verdict matches the settled status |
| `mint_fix_settled` | 25 | Each checker who attested `fixed` when the finding settles `fixed` (on top of the correctness mint) |
Every mint carries a subject (`{subject_type, subject_id}`) and rides a
partial unique index, so minting is idempotent: replays and status
oscillations return `:already_minted` and never double-pay. Moderators can
correct balances with an audited `adjustment` entry.
## Spending
- `spend_bounty_escrow` - funding a credit bounty escrows the full amount from
the sponsor at creation; cancellations and expiries refund it in full.
- `spend_priority_boost` - boosts paid for with credits.
- `receive_bounty` - the winning side of a settled credit bounty (see take
rate).
Debits fail with `:insufficient_credits` and leave the balance untouched. The
ledger is append-only and public; every entry records `balance_after`, so any
balance can be replayed.
## Take rate
Credit bounties settle net of the platform take rate: the configured rate
(`:tarakan, :market_take_rate`, 0.15 at launch) is **snapshotted onto the
bounty at creation**, so later config changes never retroactively change a
live bounty. The winner receives `credit_amount * (1 - take_rate)`; the
remainder is the platform fee.
## Fiat payouts are manual (for now)
Fiat bounties are funded through Stripe Checkout, but there is no automated
payout rail this iteration. On settlement a fiat bounty moves to
`payout_pending`; an admin pays the winner off-platform and records the fact
with `Market.mark_paid/2` (`payout_pending → paid`, audited as
`bounty_paid`). Cancellation of a funded fiat bounty refunds via Stripe.
## Invariants
- **Credits are never purchasable.** Stripe sells subscriptions and fiat
bounties; there is no way to buy a credit balance.
- **Credits are non-transferable.** The only movements are mints, spends,
bounty escrow/settlement, and moderator adjustments.
- **Money never influences finding status.** Status is decided by independent
checks and verification quorum. Credits are minted *because* a status
settled; bounties pay for work, not for outcomes on the record. A paid
feature can buy alerts, API limits, or handling - never a `verified` label.