psy-ana-coder — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited psy-ana-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.
Receives the analysis config YAML produced by psy-ana-designer, and generates either R or Python analysis scripts according to the user's language preference. R and Python share the same analysis logic — config field mapping, model selection, figure types, and report structure are fully identical; the only differences lie in the specific API calls.
Does not design analyses — only implements a confirmed analysis plan.
Analysis config YAML
│
├── User language = R → r/ (tidyverse, lme4, ggplot2, RMarkdown)
└── User language = Python → python/ (pandas, statsmodels, seaborn, Jupyter)Each platform includes 4 components: spec/ (API specification + anti-patterns), mapping/ (config-to-code mappings), checklist/ (audit checklist items), demo/ (complete example).
Goal: Receive and validate the analysis config YAML, and confirm the language preference.
"Please provide the analysis config YAML generated by psy-ana-designer. You may paste its content, or provide a file path (e.g., analysis_config.yaml)."Validate immediately after reading the config:
version field exists and is compatible (currently supports v1.0)design.design_type, design.dvs, model.seedquestions[] entryrt_lower is numeric, correction is an allowed value, etc.)Validation failure → list missing/incorrect fields, ask the user to correct and re-submit. Do not proceed.
"Should the analysis script use R or Python?"
Route to the corresponding platform (r/ or python/) based on the answer. If the user has no preference, default to R (more mature ecosystem).
Display the generation plan:
"Confirm the plan above is correct? Then code generation will begin."
After user confirmation, proceed to generation.
| # | Rule |
|---|---|
| 1 | Seed not set → do not deliver |
| 2 | Exclusion log missing → do not deliver |
| 3 | Assumption test code missing → do not deliver |
| 4 | Effect size code missing → do not deliver |
| 5 | Multiple comparison scheme not reflected → do not deliver |
| 6 | Environment info (sessionInfo/sys.version) not output → do not deliver |
| 7 | Never generate code with hardcoded paths |
| 8 | Comment language MUST match user language → do not deliver |
The logic below applies to both R and Python equally. For platform-specific API mappings, see each platform's mapping/ file.All generated code comments must use the user's language. Chinese user → Chinese comments, English user → English comments. Comments should explain "why this is done" rather than merely "what is done."
Each step's comments should include:
The comment style follows "pedagogical comments" — enabling a colleague unfamiliar with this analysis method to understand what every step does and why it is done.
1. Title comment Experiment name, model, date, seed
2. Environment setup Package loading, seed, global options
3. Data import Read + column name validation (missing column → error)
4. Data cleaning RT filtering → correct trials → participant exclusion → SD exclusion → missing data handling
5. Exclusion log Print exclusion counts and proportions at each step
6. Descriptive stats n, mean, sd, se, ci95, median, mad, grouped by condition
7. Assumption tests Shapiro-Wilk + QQ plot + Levene/Mauchly (as needed)
8. Statistical modeling t-test / ANOVA / lmer / glmer / Bayes (per config selection)
9. Effect size Cohen's d / η²p / R² / OR
10. Post-hoc comparisons Estimated marginal means + multiple comparison correction
11. Figure generation Raincloud / individual lines / boxplot / interaction plot → save to disk
12. Environment info Version + package versions(This is Phase 1 — the generation phase executed after Phase 0 validation passes.)
Priority: questions[].user_choice > decision tree default. If the designer explicitly chose a method (user_choice = method_a or method_b), use that method directly without running the decision tree below. Only use the decision tree when user_choice is unset or empty.
What is design.dvs[].type?
├── continuous (RT/score)
│ ├── design.design_type = within
│ │ ├── specified in questions → use the specified model
│ │ └── not specified → default lmer / MixedLM
│ └── design.design_type = between
│ └── default Welch t-test / oneway.test
│
└── binary (accuracy)
├── any condition accuracy > 90% or < 10%
│ └── force glmer(binomial) / Logit — ANOVA disallowed
└── accuracy between 10-90%
└── recommend glmer/Logit, ANOVA acceptable (note limitation)Formula validation: Before using model_formula, verify:
(1+condition|subject) or a similar random-effects termValidation failure → use the decision tree default model, output warning with explanation.
| Analysis | Aggregation Level |
|---|---|
| Paired t-test | Subject × Condition means |
| lmer / MixedLM | Trial level (no aggregation) |
| Descriptive statistics | Condition |
| Participant exclusion | Subject |
| Missing Field | Default Behavior |
|---|---|
cleaning.rt_lower | 150 |
cleaning.rt_upper | 3000 |
cleaning.accuracy_min | 0.6 |
cleaning.trial_exclusion | 2.5 |
cleaning.missing_policy | listwise |
model.contrast | treatment |
model.correction | bonferroni |
output.report_format | RMarkdown (R) / Jupyter (Python) |
output.figures | raincloud + individual |
output.effect_sizes | auto-select based on model type |
When using defaults, output warning: ⚠️ config did not specify {field}, using default {default}
See psy-ana-designer's plots/ directory (48 detailed figure specifications) and the R ↔ Python mapping table in this document.
| Figure Type | When to Use | Elements |
|---|---|---|
| Raincloud | Within-subjects two-group | Violin + boxplot + individual scatter |
| Individual lines | Within-subjects | One line per person + red mean |
| Boxplot + scatter | Multi-group | Boxplot + jitter |
| Interaction plot | Multi-factor | Grouped lines + error bars |
| QQ plot | Normality test | Theoretical quantiles vs actual |
| Method | Metric | Interpretation |
|---|---|---|
| t-test | Cohen's d + 95%CI | 0.2 small, 0.5 medium, 0.8 large |
| ANOVA | η²p | 0.01 small, 0.06 medium, 0.14 large |
| Mixed model | Marginal + Conditional R² | Fixed + overall |
| Logistic model | Odds Ratio + 95%CI | OR>1 odds increase |
| Method | Characteristics |
|---|---|
| Bonferroni | Most conservative, p × number of comparisons |
| FDR (BH) | Controls false discovery rate, exploratory |
| Tukey HSD | All pairwise comparisons |
| Uncorrected | Only for pre-registered single hypothesis |
For each scientific question, compare method A vs B for conclusion consistency. Flag when results are inconsistent and require further investigation.
Generate reproducible report: R → RMarkdown/Quarto, Python → Jupyter Notebook. Includes: title, exclusion summary, descriptive statistics, model results, figures, environment info.
| Operation | R | Python |
|---|---|---|
| Data import | readr::read_csv() | pandas.read_csv() |
| Filter | filter(col > x) | df[df['col'] > x] |
| Group summary | group_by() %>% summarise() | df.groupby().agg() |
| Pipe | %>% | Chained calls |
| Paired t-test | t.test(y~x, paired=TRUE) | scipy.stats.ttest_rel(a,b) |
| Independent t-test | t.test(y~x, var.equal=FALSE) | scipy.stats.ttest_ind(a,b) |
| Within-subjects ANOVA | afex::aov_ez() | pingouin.rm_anova() |
| Between-subjects ANOVA | oneway.test(y~x) | scipy.stats.f_oneway() |
| Mixed model | lme4::lmer() | statsmodels.MixedLM() |
| Logistic mixed | lme4::glmer(binomial) | statsmodels.Logit() + RE |
| Normality | shapiro.test() | scipy.stats.shapiro() |
| Homogeneity of variance | leveneTest() | scipy.stats.levene() |
| Cohen's d | effectsize::cohens_d() | pingouin.compute_effsize() |
| η² | effectsize::eta_squared() | pingouin.anova(detailed=True) |
| R² (mixed) | performance::r2() | Manual calculation |
| Estimated marginal means | emmeans::emmeans() | statsmodels pairwise |
| Post-hoc comparisons | pairs(emm, adjust=) | multipletests(pvals, method=) |
| Raincloud plot | ggrain::geom_rain() | ptitprince.RainCloud() |
| Save figure | ggsave() | plt.savefig() |
| Seed | set.seed() | np.random.seed() |
| Environment info | sessionInfo() | sys.version + pip freeze |
Analysis config YAML (input)
│
├── Target=R → r/spec/ + r/mapping/
│ → Generate: analysis.R + report.Rmd → save to output.save_path/
└── Target=Python → python/spec/ + python/mapping/
→ Generate: analysis.py + report.ipynb → save to output.save_path/
│
▼
psy-ana-reviewer (audit)After generation: Code has been saved to {output.save_path}/.
"Code generation complete. Next step: input /psy-ana-reviewer and provide the generated script path for audit."~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.