This document describes the Stroop adapter at tasks/stroop/src/index.ts.
The Stroop task is implemented using the createTaskAdapter factory:
export const stroopAdapter = createTaskAdapter({
manifest: { taskId: "stroop", ... },
run: runStroopTask,
terminate: async () => { stroopEnvironment.cleanup(); },
});run(context): Parses configuration, builds trial plan, and executes via jsPsych timeline usingTaskOrchestrator.terminate(): CallsstroopEnvironment.cleanup()(aTaskEnvironmentGuard) to reset the cursor and remove keyboard scroll blockers.
Stroop currently runs jspsych via the LifecycleManager.
Top-level sections consumed:
taskinstructionsmappingdisplaytiming(legacy fallback)stimuliconditionsplanfeedback
titleinstructions(legacy intro fallback)runner(jsPsych expected)rtTasktiming.trialDurationMstiming.fixationDurationMstiming.stimulusOnsetMstiming.responseWindowStartMstiming.responseWindowEndMsresponseTerminatesTrial(defaultfalse)postResponseContent(stimulusorblank)feedbackPhase(separateorpost_response)
Note:
- Stroop now uses shared instruction-slot parsing from
instructions:- intro:
pages|introPages|intro|screens - pre-block:
preBlockPages|beforeBlockPages|beforeBlockScreens - post-block:
postBlockPages|afterBlockPages|afterBlockScreens - end:
endPages|outroPages|end|outro
- intro:
task.instructionsremains a fallback default intro page.- Additional block-flow controls:
instructions.blockIntroTemplate(supports{blockLabel}and{nTrials})instructions.showBlockLabel(defaulttrue)instructions.preBlockBeforeBlockIntro(defaultfalse)
Required:
redKeygreenKey
Keys are normalized via core normalizeKey and must be distinct.
aperturePxpaddingYPxcueHeightPxcueMarginBottomPxframeBackgroundframeBordercueColorfixationColorfixationFontSizePxfixationFontWeightstimulusFontSizePxstimulusFontWeighttextColorByToken
Color token validation uses core createColorRegistry.
responseColorTokens(must includeredandgreen)words(inline word list)wordsCsv(path,column, optionalbasePath)colorLexicon- inline map (
mapor direct object) - optional CSV dictionary (
csv.path,csv.keyColumn,csv.valueColumn, optionalcsv.basePath)
- inline map (
valenceLists- inline:
positive[],neutral[],negative[] - optional CSV columns via
valenceLists.csv.pathandvalenceLists.csv.columns
- inline:
mode:congruenceorvalencequotaPerBlock: exact condition countsfontColorQuotaPerBlock: exact font-color countsmaxConditionRunLengthnoImmediateWordRepeat
blockCountblockTemplatelabel(supports{blockIndex})trialsfeedback(optional per-block override)beforeBlockScreens(optional string or string[]; extra continue screens before each block)afterBlockScreens(optional string or string[]; extra continue screens after block-end summary)
Legacy aliases still accepted:
preBlockInstructions->beforeBlockScreenspostBlockInstructions->afterBlockScreens
Uses core shared feedback parsing:
enableddurationMs/duration_msmessages.*style.*
- Condition sequence uses core
buildConditionSequencewith exact quota weights and max-run constraints. - Semantic labeling uses core semantic resolver utilities.
- Color token to CSS mapping uses core color registry.
- RT phase durations use core
computeRtPhaseDurations.
mode: "congruence"
congruent: word semantic color equals font color.incongruent: word semantic color is a response color but does not equal font color.neutral: word not mapped to a response color.
mode: "valence"
- condition is word valence (
positive|neutral|negative). - response criterion remains font color.
What is easy in current Stroop config:
- quickly set
plan.blockCount+plan.blockTemplate.trials - constrain condition and color distributions with:
conditions.quotaPerBlockconditions.fontColorQuotaPerBlockconditions.maxConditionRunLength
- include per-block screens with
beforeBlockScreens/afterBlockScreens
What is not currently first-class in Stroop:
- no
design.manipulationsequivalent - no per-block manipulation assignment schedule (for example alternating trial-type recipes by block)
plan.blockTemplateis one template replicatedblockCounttimes
If you need qualitatively different block recipes, current approach is to create separate variants/config files (or runtime overrides) rather than declaring multiple block templates in one Stroop config.
Each response-window trial emits:
- participant + variant fields
mode- block/trial ids and indices
wordwordColorTokenvalencefontColorTokenfontColorHexconditionLabelcorrectResponseresponseKeyresponseRtMsresponseCorrect
The Stroop implementation was completed without adding new Stroop-specific logic to core. Two generic friction points were encountered and handled task-locally:
- Multi-constraint allocation gap:
- Core has exact single-factor sequencing (
buildConditionSequence) and adjacency constraints. - It does not yet provide a generic joint allocator that simultaneously enforces condition quotas, response-color quotas, and per-cell feasibility.
- Stroop handles this by combining core condition sequencing with local color assignment retries.
- Multi-column token loading convenience:
- Core CSV loaders can read a single named column per call.
- Emotional Stroop needs multiple semantic columns (
positive,neutral,negative) in one file. - Stroop loads each column through repeated core calls and merges locally.