psy-exp-coder — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited psy-exp-coder (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
v1.3 — stable, 2026-06-10. Sub-skill of amazing-psycoder.
Translate a completed experiment config YAML into production-quality platform code. This is the code generation layer — it receives a fully specified config (from psy-exp-designer) and outputs runnable experiment code for the target platform. See Platform Support Status for current capabilities.
输出即交付。 Generated code must be runnable as-is — not a draft, not pseudocode. The user can take the output file and collect data immediately. All editable parameters sit at the top of the script where non-programmers can adjust them without reading logic code. Font configuration uses a FONT_CONFIG toggle block so users on any OS can switch between auto-detect and manual path.
Core principles:
KbCheck for RT, the spec's KbQueueCheck wins.time.sleep(), event.getKeys(maxWait=), KbCheck for RT, in-loop disk I/O are blocked. The Post-Generation Quality Gate catches violations before delivery.psy-exp-reviewer before collecting data. The reviewer is the mandatory quality gate between code generation and data collection.下一步: 代码生成完成。输入/psy-exp-reviewer并提供生成的实验代码路径进行审计。审计通过 (ready_for_collection) 后方可正式采集数据。 Next step: Code generation is complete. Run/psy-exp-reviewerwith the generated experiment code path for audit. Data collection may only proceed after the audit passes (ready_for_collection).
After code generation completes → route to psy-exp-reviewer for mandatory audit. No experiment code proceeds to data collection without passing reviewer audit.
This is the highest-priority output rule. Every string in generated experiment code must use the language the user communicated in during the design workflow (orchestrator Phase 1-5). Paradigm reference files and config schemas may contain example text in a specific language — these are placeholders showing the CONCEPT, not the literal text to generate.
| Content type | Language rule |
|---|---|
| Instruction text, rest prompts, debrief screens | User's language |
| Stimulus words, feedback text ("Correct!", "Too slow!") | User's language |
| Button labels, category tags, UI elements | User's language |
| Code comments, README | User's language |
| Variable names, function names | English (universal) |
| Data column names | English (recommended) |
Language determination is automatic from the design workflow conversation:
Critical: NEVER copy stimulus text, instruction text, or feedback text from paradigm reference files into generated code without translating to the user's language. The paradigm reference's language is accidental — the user's language from the design workflow is authoritative.
All three platforms share the same Generation Pipeline (Config→Code). The flow is identical — only the platform-specific mapping (L2) and code skeleton (L1) differ. Each platform README documents the flow with its platform-specific implementation details.
| Platform | Status | What to do |
|---|---|---|
| PsychoPy (2024.x+, Python 3.10+) | 4 layers complete | Generate production-ready code from config YAML. See psychopy/ |
| jsPsych (JavaScript, 7.x) | 4 layers complete | Generate code from config YAML. 25 paradigm files. See jspsych/ |
| Psychtoolbox (MATLAB) | 4 layers complete | Generate code from config YAML. 5 paradigm files + 100 demos. See psychtoolbox/ |
All three platforms use the unified generation flow documented in their respective README files. Do not treat any platform as "unsupported" — if a platform is requested, apply the same Generation Pipeline using that platform's L1 skeleton and L2 mapping.
Platform-specific implementation details live in subdirectories. Open the relevant platform README when generating or debugging code:
psychopy/ ← 统一生成流水线,4层全满
README.md → 平台入口(生成流程 + 强制 API + 范式差异速查)
spec/ → L1: Canonical Skeleton + API 规范 + 反模式
mapping/ → L2: Config→代码映射 + 三种窗口模式 + 三版本对照
paradigms/ → L3: 27 个范式(索引见 paradigms/README.md)
demo/_raw/ → L4: 45 个 .py
jspsych/ ← 统一生成流水线,4层全满
README.md → 平台入口(生成流程 + 强制 API + 平台特性)
spec/ → L1: Canonical Skeleton + API 规范 + 反模式
mapping/ → L2: Config→timeline 映射 + 6.1.0→7.x 迁移表
paradigms/ → L3: 25 个范式(索引见 paradigms/README.md)
demo/_raw/ → L4: 23 个 .js
psychtoolbox/ ← 统一生成流水线,4层全满
README.md → 平台入口(生成流程 + 强制 API + 范式差异速查)
spec/ → L1: Canonical Skeleton + API 规范 + 反模式 + 入门示例
mapping/ → L2: Config→MATLAB 映射 + 三种帧循环模式
paradigms/ → L3: 5 个范式(索引见 paradigms/README.md)
demo/_raw/ → L4: 100 个 .md(按功能分类)Each platform paradigm file contains two sections: Experiment Logic (window sequence, accuracy rules, condition structure) and Code Examples (complete runnable code — but API patterns may be outdated; always defer to the spec's Canonical Skeleton).
Every platform uses the same 4-layer priority stack. The layers are identical across platforms — only the fill status of each layer varies:
Layer 1: spec/README.md ← 最高优先级:平台 API 规范、反模式表、强制模式
Layer 2: Config → Code Mapping ← 结构映射:config YAML 字段 → 平台代码
Layer 3: Paradigm reference files ← 范式逻辑:SSD staircase、match detection、显示布局
Layer 4: Raw demo code ← 最低优先级:仅参考逻辑,不参考 API 模式When layers conflict, higher layers always take precedence. Lower layers provide logic and algorithms but never override higher-layer API patterns.
Fill status per platform:
| Layer | PsychoPy | jsPsych | Psychtoolbox |
|---|---|---|---|
L1 spec/ | ✅ psychopy/spec/README.md | ✅ jspsych/spec/README.md | ✅ psychtoolbox/spec/README.md |
L2 mapping/ | ✅ psychopy/mapping/README.md | ✅ jspsych/mapping/README.md | ✅ psychtoolbox/mapping/README.md |
L3 paradigms/ | ✅ 27个 (psychopy/paradigms/) | ✅ 25个 (jspsych/paradigms/) | ✅ 5个 (psychtoolbox/paradigms/) |
L4 demo/_raw/ | ✅ 45个 .py (psychopy/demo/_raw/) | ✅ 23个 .js (jspsych/demo/_raw/) | ✅ 100个 .md (psychtoolbox/demo/_raw/ by category) |
All three platforms have all 4 layers filled. The generation flow is identical across platforms. Apply the same priority rule regardless of platform: spec skeleton > spec anti-patterns > config→code mapping > paradigm logic > demos.
Every generated experiment script follows this structure, regardless of platform (PsychoPy, jsPsych, Psychtoolbox):
1. Imports / dependencies
2. Experiment parameters (all editable at top)
- Include OS detection + font path setup if text stimuli used (esp. CJK)
3. Display setup (window / canvas / screen)
4. Stimulus preloading (outside trial loop)
5. Condition file loading / generation
6. Helper functions
7. Instruction routine
8. Practice routine (with feedback)
9. Main experimental loop
a. Block-level setup
b. Trial randomization
c. Per-trial: fixation → stimulus → response → feedback → ITI
d. Block-level feedback (if applicable)
10. Data saving (incremental, try/finally)
11. Cleanup / quit (always with escape / abort handler)
12. Package as platform file + generate READMEAfter generating code, always package it into two deliverable files:
1. Platform experiment file — the runnable code saved with the correct extension:
| Platform | Extension | Example |
|---|---|---|
| PsychoPy | .py | stroop_experiment.py |
| jsPsych | .js (or .html if standalone) | stroop_experiment.js |
| Psychtoolbox | .m | stroop_experiment.m |
2. README file — a human-readable companion document saved alongside the code:
The README describes the experiment logic and how to run it. It must include:
Language consistency: See Language Consistency (Red Line) above. All text — README, comments, instructions, stimuli, feedback, UI labels — must match the user's language. Do not mix languages.
When the user provides a config.yaml + condition xlsx files, translate the config directly to platform code using the structure defined in the Code Template above. The user decides the platform — this structure is platform-independent.
| Config section | Code generated |
|---|---|
name | Script docstring |
paradigm | Load paradigm knowledge, apply paradigm-specific accuracy logic |
stimulus_folder | Global path prepended to image-file {column} references |
windows[] | Trial event loop: each window = one screen update / flip |
windows[].content: "{col}" | Text stimulus or image stimulus from condition row column |
windows[].duration: N | Fixed-duration timer (N ms) |
windows[].duration: [min, max] | Random duration in [min, max] ms |
windows[].response: [keys] | Response collection with timed loop (platform-specific: see implementation guide) |
windows[].rt_onset | Which window's display onset starts the RT clock. "self" = this window. A window name = clock reset at that window's display |
blocks[] | Block loop + condition file loading |
blocks[].condition_file | Load condition data from xlsx/csv |
response_rules.correct | Accuracy evaluation in trial loop |
paradigm_config | Paradigm-specific logic (SSD staircase, n-back target detection, etc.) |
display | Display / window creation parameters |
font | Font specification (family, size, file path); auto-detect CJK font by OS if Chinese text used |
audio | Sound preloading + playback; platform-specific backend selection (PTB for low latency) |
participant_info | Subject ID dialog / form; fields (age, gender, handedness), dropdown lists, session number |
output | Data save: filename pattern, incremental flush |
First, run the 9 config-level validation rules from config-schema.md. These are authoritative for schema correctness.
Then run these code-generation-specific checks:
paradigms/) has been read for accuracy rules, timing conventions, and edge casesplatform field matches a supported platform. If not PsychoPy, state limitations before generatingrt_onset maps to a real window name. If rt_onset is missing, ask before generating — this is a blocking checktry/finally block wraps the main experiment loop, with per-trial flushAfter generating code, run this checklist against the output file before presenting it to the user. Any failure = fix before delivery.
| # | Check | How to verify |
|---|---|---|
| 1 | Spec skeleton used | Code structure matches the canonical skeleton from the platform spec (spec/README.md §Canonical Code Skeleton). If the skeleton and the generated code diverge structurally, the skeleton is correct — fix the code. |
| 2 | No spec anti-patterns | Scan code against the anti-pattern table in the platform spec. Every forbidden pattern (time.sleep, KbCheck for RT, event.getKeys(maxWait=), jsPsych.init(), WaitSecs, etc.) = reject. |
| 3 | Spec API patterns used | Paradigm reference files provide experiment logic (window sequence, accuracy rules, condition structure) — NOT API patterns. If any API pattern in the generated code came from a paradigms/demo file rather than the spec canonical skeleton, fix it. |
| 4 | All parameters at top | Every editable value (subject ID, durations, key mappings, condition file paths, colors) is in the parameters block. No magic numbers in logic code. |
| 5 | Escape in every loop | Every while loop that contains Flip/flip/frame-draw includes an escape/abort check. |
| 6 | RT source verified | Confirm RT comes from the correct source for the platform: PsychoPy = key.rt (USB HID timestamp), PTB = firstPress - VBLTimestamp, jsPsych = data.rt (automatic). No manual clock.getTime() or GetSecs() for RT. |
| 7 | Incremental save | Per-trial data flush. Crash after trial N → N rows of data survive. |
| 8 | Preload outside loop | No imread/MakeTexture/ImageStim() constructor inside the trial loop. All stimuli created before the loop. |
| 9 | FONT_CONFIG toggle | If experiment uses Chinese text, FONT_AUTO_DETECT/MANUAL_FONT_PATH block is present in the parameters section. |
Before generating code, confirm the programming skill's Gate 5 (Final Design Review) has passed — the Trial Window Timeline and full Design Decision Registry have been presented to and confirmed by the user. The config YAML is an internal artifact — do NOT display it to the user.
When generating code, output:
.py / .js / .m), all editable parameters at the top, FONT_CONFIG toggle block if CJK text used, code comments in the user's languagedata/.The config YAML is passed silently from orchestrator to coder — it is never displayed to the user.
When the user reports that generated code has an error or unexpected behavior:
pip install <package>.stimulus_folder.try/finally block issue. Verify flush logic, check if experiment crashed before finally block.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.