Skip to content

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 row

Audition 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_close

Arena 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 slots

Main Code Paths

PathPurpose
backend/src/modules/lifecycle/audition/service.tsSubmit, list, evaluate, void, and refund audition runs.
backend/src/modules/lifecycle/audition/evaluators.tsProfit-target and noop evaluator registry.
backend/src/modules/lifecycle/arena-entry/service.tsPromotion Queue and Arena slot admission orchestration.
backend/src/modules/lifecycle/repositories/audition-runs.tsaudition_runs persistence.
backend/src/modules/lifecycle/repositories/audition-refunds.tsRefund authorization persistence.
backend/src/modules/lifecycle/repositories/promotion-queue.tsPromotion Queue persistence.
backend/src/modules/lifecycle/repositories/arena-memberships.tsArena membership persistence.
backend/src/workers/audition-evaluator.tsDue-audition evaluator worker.
backend/src/workers/arena-entry.tsArena Entry sync worker.

State And Tables

MigrationTables
0009_audition_runs.sqlaudition_runs
0012_audition_refunds.sqlaudition_refund_authorizations
0020_competition_arena_entry.sqlpromotion_queue_entries, arena_clone_memberships
TableTechnical significance
audition_runsAudition status, prop account link, evaluator, timing, lineage, purchase id.
audition_refund_authorizationsWrite-once SignedVault withdrawal authorization for voided auditions.
promotion_queue_entriesWaiting/promoted/removed entries from passed auditions.
arena_clone_membershipsActive/retired/removed Arena clone memberships.

Routes And Workers

SurfaceAuthPurpose
POST /api/v1/lifecycle/auditionsBearer ownerSubmit paid audition and create/reuse prop account.
GET /api/v1/lifecycle/auditions/:idBearer ownerRead audition run.
GET /api/v1/lifecycle/clones/:cloneId/auditionsBearer ownerList clone auditions.
POST /api/v1/lifecycle/auditions/:id/evaluateService tokenEvaluate one audition.
POST /api/v1/lifecycle/auditions/evaluate-dueService tokenEvaluate due auditions.
POST /api/v1/lifecycle/auditions/:id/voidService tokenVoid an audition.
GET /api/v1/lifecycle/arenaPublicArena capacity, active count, queue depth.
GET /api/v1/lifecycle/arena/clonesPublicActive Arena clone cards.
GET /api/v1/lifecycle/promotion-queuePublicWaiting Promotion Queue entries.
POST /api/v1/lifecycle/arena/sync-entryService tokenSync passed auditions into Queue/Arena.
POST /api/v1/lifecycle/promotion-queue/:id/removeService tokenAdmin remove waiting queue entry.
POST /api/v1/lifecycle/arena/clones/:cloneId/retireService tokenAdmin retire active Arena clone.
POST /api/v1/lifecycle/arena/clones/:cloneId/removeService tokenAdmin remove active Arena clone.
npm run lifecycle:auditions:workerWorkerLong-running due-audition evaluator.
npm run lifecycle:arena-entry:workerWorkerLong-running Arena Entry sync.

Worker defaults:

WorkerDefault cadence
Due audition evaluator5 minutes
Arena Entry sync5 minutes

Evaluation Policy

Default audition settings:

SettingDefault
Duration21,600 seconds
Starting balance100,000 USDC
Evaluatorprofit_target_v1
Profit target2% return
Max drawdown allowed25%

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 economyPurchaseId returns 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 running auditions after endsAt unless forced.
  • Evaluation transitions through evaluating before terminal passed or failed.
  • 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.ts

Known 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.