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.
Authoritative-source boundary: never load or copy files underpython/demo/orr/demo/during generation. They are quarantined historical demonstrations and do not satisfy the v1.4.0 analysis contract. Use only the confirmed config plus the current spec, mapping, and checklist selected below.
v1.4.0 — unified evidence-gated contract, 2026-07-23. Sub-skill of amazing-psycoder.
Receive the analysis config from psy-ana-designer and implement it in R or Python. Preserve the same estimand and decision rules across languages, but do not claim API/capability equivalence: if a selected model has no validated implementation in the chosen ecosystem, block or obtain approval for a scientifically equivalent alternative.
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 authoritative spec/, mapping/, and checklist/ components. Existing demo/ directories are quarantined historical material and are excluded from generation context.
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 is compatible (current contract: v1.2)analysis_mode, exact runtime.language/runtime.language_version/dependency strategy/concrete dependency_file/target environment, design.design_type, design.observation_level, design.dvs, questions[].estimand, questions[].selected_method, and model.stochasticmodel.stochastic: true, model.seed is required; deterministic plans need no ceremonial seedquestions[] entryrt_lower is numeric when used, correction is explicit and supported by the selected inference, etc.)Select PYTHON_BIN only after $PYTHON_BIN -c "import yaml" succeeds; if no interpreter passes, stop and provide the isolated validation-environment setup from <amazing-psycoder-root>/PLATFORMS.md. Run $PYTHON_BIN <amazing-psycoder-root>/scripts/validate_analysis.py <analysis_config.yaml> and treat every error as blocking. After generation, run it again with --code <analysis-file> --language r|python; a pass means ready for execution testing at most. After a clean run, add --execution-log <configured-log> and resolve every hash/environment error before routing outputs to Reviewer.
Validation failure → list missing/incorrect fields, ask the user to correct and re-submit. Do not proceed.
Route to the platform declared in runtime.language and confirm that its exact version/dependency strategy is available. Generate the declared runtime.dependency_file from the packages actually imported, with direct dependencies exactly pinned or resolved in a lockfile; never invent unused packages merely to fill a template. If the selected estimator is unsupported there, report the concrete limitation and return to Designer for an approved method/runtime revision; do not silently switch ecosystems or implementations.
Display the generation plan:
"Confirm the plan above is correct? Then code generation will begin."
After user confirmation, proceed to generation.
| # | Rule |
|---|---|
| 1 | Stochastic step without a seed/control strategy → do not deliver |
| 2 | Exclusion log missing → do not deliver |
| 3 | Applicable diagnostics/fallback code missing → do not deliver; never add irrelevant omnibus assumption tests |
| 4 | Claim-appropriate effect estimate and uncertainty 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 |
| 9 | Declared dependency artifact absent, incomplete for actual imports, or inconsistent with the target runtime → do not deliver |
| 10 | Execution manifest is written only on success, so a failed clean run leaves no machine-readable failure evidence → 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, estimand/model, date, config version
2. Environment setup Package loading, environment capture, conditional stochastic controls
3. Data import Read + column name validation (missing column → error)
4. Data cleaning Apply only the config-declared rules in their declared order; never assume correct-only or SD trimming
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. Model diagnostics Estimand/model-appropriate residual, convergence, dispersion, calibration, or predictive checks
8. Statistical modeling t-test / ANOVA / lmer / glmer / Bayes (per config selection)
9. Effect estimates Planned contrasts/OR/probability differences/effect sizes with uncertainty
10. Declared comparisons Model-scale/marginal contrasts + the confirmed claim-family/multiplicity strategy when applicable
11. Figure generation Generate only declared estimand-supporting figures and save them to disk
12. Environment info Version + package versions(This is Phase 1 — the generation phase executed after Phase 0 validation passes.)
Priority: implement questions[].selected_method and its confirmed formula/estimand. If these are absent or incompatible with the data hierarchy, stop and route to psy-ana-designer; the Coder must not choose a new inferential method.
selected_method + estimand + outcome family + observation hierarchy
├── compatible → implement exactly and add declared diagnostics/sensitivity rules
├── unsupported by chosen language/runtime → report concrete dependency limitation and return for an approved alternative
└── incompatible/unresolved → stop; route to psy-ana-designerFormula/dependence validation: Before using model_formula and dependence_structure, verify:
Validation failure → block generation and return an actionable config error. Never silently substitute another model.
| Analysis | Aggregation Level |
|---|---|
| Paired t-test | Subject × Condition means |
| lmer / MixedLM | Trial level (no aggregation) |
| Descriptive statistics | Condition |
| Participant exclusion | Subject |
Do not silently invent cleaning thresholds, missing-data policy, contrasts, multiplicity correction, figures, or effect estimates. Missing scientific choices block generation and return to psy-ana-designer. Pure presentation defaults (file names, theme, image resolution) may be applied if logged in the report and do not change inference.
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 | Design-appropriate standardized and/or raw contrast + 95% CI | Interpret against the construct and domain evidence; do not impose universal small/medium/large cutoffs |
| ANOVA | Estimand-compatible contrast and CI; η²/ω² when useful | Interpret magnitude in the construct, scale, and design context; do not impose universal cutoffs |
| Mixed model | Planned marginal contrast + CI; optionally marginal/conditional R² | Focal effect plus model fit |
| Logistic model | Odds ratio and/or probability-scale contrast + 95% CI | State the reference direction and interpret on a domain-relevant scale |
| Method | Characteristics |
|---|---|
| Holm / Bonferroni | Family-wise error control for a declared family; Holm is often less conservative |
| FDR (BH) | False-discovery-rate control for a declared discovery family |
| Tukey HSD | Simultaneous inference for a declared all-pairwise family under its model assumptions |
| Planned/hierarchical/no adjustment | Use when the question structure justifies it and record the claim family and rationale |
Run only prespecified sensitivity analyses (cleaning, missingness, distribution/random structure, or estimator variants). Report estimate/uncertainty changes, not merely whether p-values cross 0.05.
Generate a reproducible report: R → RMarkdown/Quarto, Python → Jupyter or a script-rendered HTML report. Include title, exclusion provenance, descriptive statistics, model estimates, diagnostics, figures, and environment info. When execution is possible, run in a clean process and save analysis-run.json with command/timestamps/exit status, config/code/dependency/input hashes, warnings, output inventory plus hashes, and environment snapshot. Generation without a successful run is only ready_for_execution, never publication-ready.
| Operation | R | Python |
|---|---|---|
| Data import | Dispatch from declared format to readr/readxl/arrow/jsonlite | Dispatch from declared format to the matching pandas reader |
| 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 Welch t-test | t.test(y~x, var.equal=FALSE) | scipy.stats.ttest_ind(a,b,equal_var=False) |
| 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) | Bambi Bernoulli multilevel model, or a documented BinomialBayesMixedGLM design within its limits; plain Logit() has no random effects |
| Distribution diagnostics | Model-specific residual/convergence/dispersion checks | Model-specific residual/convergence/dispersion or posterior-predictive checks |
| 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 | exact R-version check + sessionInfo() + declared dependency artifact | exact Python-version check + platform/package snapshot + declared dependency artifact |
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/
Both routes also generate runtime.dependency_file beside the project config.
│
▼
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.