Appearance
Lifecycle Module
Overview
The lifecycle module owns product competition state transitions. Today that means paid auditions, audition evaluation/retry/void/refund authorization, Promotion Queue, and Arena admission.
Later lifecycle work will add race launch, live windows, settlement orchestration, retirement, and Hall of Fame preservation.
Lifecycle creates and consumes prop accounts through Prop Trading services. It does not directly mutate prop balances, fills, positions, PnL, or ledger truth.
Responsibilities
- Submit paid auditions and create/start audition prop accounts.
- List audition status for owners.
- Evaluate due auditions with registered evaluators.
- Support retries after failed or voided auditions.
- Void invalid auditions through service-token/admin paths.
- Authorize refunds for voided auditions.
- Sync passed auditions into Promotion Queue and Arena slots.
- Enforce approved public profile gate for Arena admission.
- Provide public Arena and Promotion Queue reads.
- Provide service-token/admin removal and retirement controls.
Boundary Rules
- Economy owns audition-fee purchase facts; Lifecycle consumes the active entitlement's purchase id for the first included audition and fresh retry purchases.
- Clone Service owns clone identity, owner checks, public profile approval, and entitlements.
- Prop Trading owns execution truth and account terminal transitions.
- Lifecycle evaluator logic consumes Prop Trading snapshots; it does not compute fills from raw market data.
- Race tickets and payout facts belong to future Economy V2, while race state belongs here.
Runtime Flow
Audition submit:
text
Authenticated owner submits clone
-> validate clone ownership and non-mock entitlement
-> resolve the current entitlement's economy purchase as the paid audition slot
-> validate evaluator and allowed symbols
-> create idempotent prop account with parentType audition
-> start prop account
-> insert audition_runs rowAudition evaluation:
text
Worker lists running auditions with ends_at <= now
-> mark run evaluating
-> read Prop Trading snapshot
-> run evaluator
-> mark passed or failed
-> complete prop account with lifecycle_closeArena Entry:
text
Worker scans passed auditions
-> skip clones already active or waiting
-> skip clones without approved public profile
-> insert waiting Promotion Queue entry
-> promote waiting entries into open Arena slotsMain Code Paths
| Path | Purpose |
|---|---|
backend/src/modules/lifecycle/audition/service.ts | Submit, list, evaluate, void, and refund audition runs. |
backend/src/modules/lifecycle/audition/evaluators.ts | Profit-target and noop evaluator registry. |
backend/src/modules/lifecycle/arena-entry/service.ts | Promotion Queue and Arena slot admission orchestration. |
backend/src/modules/lifecycle/repositories/audition-runs.ts | audition_runs persistence. |
backend/src/modules/lifecycle/repositories/audition-refunds.ts | Refund authorization persistence. |
backend/src/modules/lifecycle/repositories/promotion-queue.ts | Promotion Queue persistence. |
backend/src/modules/lifecycle/repositories/arena-memberships.ts | Arena membership persistence. |
backend/src/workers/audition-evaluator.ts | Due-audition evaluator worker. |
backend/src/workers/arena-entry.ts | Arena Entry sync worker. |
State And Tables
| Migration | Tables |
|---|---|
0009_audition_runs.sql | audition_runs |
0012_audition_refunds.sql | audition_refund_authorizations |
0020_competition_arena_entry.sql | promotion_queue_entries, arena_clone_memberships |
| Table | Technical significance |
|---|---|
audition_runs | Audition status, prop account link, evaluator, timing, lineage, purchase id. |
audition_refund_authorizations | Write-once SignedVault withdrawal authorization for voided auditions. |
promotion_queue_entries | Waiting/promoted/removed entries from passed auditions. |
arena_clone_memberships | Active/retired/removed Arena clone memberships. |
Routes And Workers
| Surface | Auth | Purpose |
|---|---|---|
POST /api/v1/lifecycle/auditions | Bearer owner | Submit paid audition and create/reuse prop account. |
GET /api/v1/lifecycle/auditions/:id | Bearer owner | Read audition run. |
GET /api/v1/lifecycle/clones/:cloneId/auditions | Bearer owner | List clone auditions. |
POST /api/v1/lifecycle/auditions/:id/evaluate | Service token | Evaluate one audition. |
POST /api/v1/lifecycle/auditions/evaluate-due | Service token | Evaluate due auditions. |
POST /api/v1/lifecycle/auditions/:id/void | Service token | Void an audition. |
GET /api/v1/lifecycle/arena | Public | Arena capacity, active count, queue depth. |
GET /api/v1/lifecycle/arena/clones | Public | Active Arena clone cards. |
GET /api/v1/lifecycle/promotion-queue | Public | Waiting Promotion Queue entries. |
POST /api/v1/lifecycle/arena/sync-entry | Service token | Sync passed auditions into Queue/Arena. |
POST /api/v1/lifecycle/promotion-queue/:id/remove | Service token | Admin remove waiting queue entry. |
POST /api/v1/lifecycle/arena/clones/:cloneId/retire | Service token | Admin retire active Arena clone. |
POST /api/v1/lifecycle/arena/clones/:cloneId/remove | Service token | Admin remove active Arena clone. |
npm run lifecycle:auditions:worker | Worker | Long-running due-audition evaluator. |
npm run lifecycle:arena-entry:worker | Worker | Long-running Arena Entry sync. |
Worker defaults:
| Worker | Default cadence |
|---|---|
| Due audition evaluator | 5 minutes |
| Arena Entry sync | 5 minutes |
Evaluation Policy
Default audition settings:
| Setting | Default |
|---|---|
| Duration | 21,600 seconds |
| Starting balance | 100,000 USDC |
| Evaluator | profit_target_v1 |
| Profit target | 2% return |
| Max drawdown allowed | 25% |
noop_always_pass is still registered for debug/controlled paths.
Failure Behavior
- Submit requires clone ownership, non-mock entitlement, registered evaluator, and nonempty allowed symbols.
- Default idempotency key is based on clone id and creation second unless a caller supplies one.
- Reusing an
economyPurchaseIdreturns the existing audition/prop account when already linked. - Retry requires a previous failed or voided audition and a fresh purchase-backed entitlement; reusing the first clone-purchase slot is rejected.
- Evaluation only runs for
runningauditions afterendsAtunless forced. - Evaluation transitions through
evaluatingbefore terminalpassedorfailed. - Void only applies to non-terminal running/evaluating auditions.
- Refund authorization only applies to voided auditions and is write-once/idempotent per audition.
- Arena sync skips already active/waiting clones and clones without approved public profiles.
Debugging Notes
- If audition submit fails, check clone owner, entitlement source/status, purchase id, evaluator id, and allowed symbols.
- If an audition is due but not evaluated, check
ends_at, status, evaluator worker heartbeat, and service-token route access. - If an audition evaluation looks wrong, inspect the Prop Trading snapshot used by the evaluator.
- If a passed clone does not enter Arena, check public profile approval, existing queue entry, existing active membership, and max active slots.
- If refund authorization fails, confirm the audition is voided and SignedVault withdrawal signer config is present.
Tests
bash
cd backend
npm run typecheck
node --import tsx --test test/api-lifecycle.test.ts test/audition-lifecycle-service.test.ts test/arena-entry-service.test.ts test/profit-target-evaluator.test.tsKnown Gaps
- Frontend audition status/retry UI.
- Frontend Arena/Queue display and operator views.
- Race lifecycle tables and workers.
- Race ticket positions and settlement orchestration.
- Retirement and Hall of Fame preservation.