name: empirica-implementation description: Implement an Empirica experiment from a spec using the correct Classic lifecycle primitives, updating server callbacks, client components, and treatment/lobby config consistently.
Use this implementation checklist:
Runtime command policy for this repo:
- Do not use
npm run build/npm testto validate the Empirica app. - Only install dependencies with
npm installinclient/andserver/. - Start and run the app with
empiricafrom repository root. - If a full integration build check is needed, run
empirica bundlefrom repository root.
- Confirm relevant Empirica references before editing:
- docs: https://docs.empirica.ly/
- framework repo: https://github.com/empiricaly/empirica
- docs repo: https://github.com/empiricaly/docsv2
- project reference map:
schema/empirica-reference.jsonif present 0.5 Configure required admin auth placeholders before implementation/testing: - open
.empirica/empirica.toml - replace
CHANGE_ME_SRTOKENandCHANGE_ME_PASSWORDwith real values - use those configured admin credentials consistently in automation/test commands
Generalizable implementation defaults:
- Preserve lifecycle semantics: intro/exit are asynchronous; rounds/stages are synchronous.
- Keep scope boundaries strict: game/player/round/stage attributes should be intentional and documented.
- For async writes outside lifecycle callbacks (intervals, API callbacks, workers), call
await Empirica.flush()afterset(...). - Load env before callback module initialization (dotenv first, then import callbacks) when top-level env reads exist.
- Prefer stable, explicit shared-state keys for UI/server coordination; avoid implicit state coupling.
Before coding, present the UI plan to the researcher:
- show proposed participant screens by stage
- call out interactions and where each decision is saved (
player.stage,player.round, etc.) - request explicit feedback before implementation
Translate experiment design into Empirica config:
- update
.empirica/treatments.yaml - update
.empirica/lobbies.yaml - include an admin-run plan that states expected batch and randomization setup
- update
Implement lifecycle logic in
server/src/callbacks.js:- create rounds/stages in
onGameStart - compute outcomes in
onStageEndedoronRoundEnded - store all analytic variables with explicit keys
- avoid silent defaults for missing critical values
- if using async timers/workers/API responses, flush writes (
await Empirica.flush())
- create rounds/stages in
Implement player UI in
client/src:- round/stage routing in
Stage.jsx - task components in
client/src/task-designor new feature folders - profile/summaries in
Profile.jsx - intro/exit survey fields in
client/src/introandclient/src/exit - wire intro/exit in Empirica-native way in
client/src/App.jsx:- use
EmpiricaContextpropsconsent,introSteps,exitSteps - provide intro/exit components as ordered arrays
- keep each step as a focused React component under
client/src/introorclient/src/exit
- use
- round/stage routing in
Keep schema keys synchronized across server and client:
- every
get("key")should have a clear producerset("key") - use stable, analysis-friendly key names and annotate each key with Empirica scope in final report
- every
Verify by running Empirica-native flow:
empirica bundlefor integration build check- then run autonomous test and screenshot workflow from the testing skill
- ensure the autonomous run has strict completion criteria:
- all simulated participants reach final exit
- treatment-specific mechanics are exercised (not just nominal page traversal)
- failures block "test passed" status until resolved
Required output after coding:
- list of touched files
- list of new schema keys grouped by
game/player/round/stage - intro/exit mapping summary:
- consent component used
- introSteps order
- exitSteps order
- Empirica references consulted
- remaining assumptions or limits