Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Statistical analysis for medical research papers. Generates reproducible Python/R code with publication-ready tables and figures. Supports diagnostic accuracy, inter-rater agreement, meta-analysis, survival analysis, survey data, group comparisons, regression, propensity score, and repeated measures.
.claude/skills/aperivue-analyze-stats/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 666% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 763% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 1261% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 542% | 0% |
| case-07 | ✓→✗ | ▼ Worse | 456% | 0% |
You are assisting a medical researcher with statistical analyses for medical research papers. Generate reproducible code (Python preferred, R when necessary) that produces publication-ready tables and figures following journal standards for medical imaging research.
Before reading any data file, check whether it might contain Protected Health Information (PHI):
*_deidentified.* files exist in the working directory, use those preferentially.*_deidentified.* counterpart), warn the user (ask in the user's preferred language):> "Does this data contain patient identifiers (names, national ID / RRN, contact details, etc.)? > If so, please de-identify it first with the /deidentify skill."
encounter them while reading data, warn the user and suggest running /deidentify.
${CLAUDE_SKILL_DIR}/references/templates/ -- reusable analysis scripts${CLAUDE_SKILL_DIR}/references/analysis_guides/ -- on-demand methodology references${CLAUDE_SKILL_DIR}/references/table-standards/ -- journal-specific table formattingtable-standards.md -- universal rules, AMA rules, footnote system, mistakes checklistjournal-profiles/ -- YAML profiles per journal (radiology, jama, nejm, lancet, eur_rad, ajr)table-types/ -- templates per table type (Table 1, diagnostic accuracy, regression, survival/Cox, agreement/reliability, meta-analysis, model comparison, incremental value, reader study (MRMC))tool-comparison.md -- R/Python tool comparison and recommended pipelines${CLAUDE_SKILL_DIR}/references/style/figure_style.mplstyle2_Data/Read relevant templates before generating analysis code. For complex analysis types (regression, propensity score, repeated measures), also load the corresponding guide from analysis_guides/ to ensure correct methodology and reporting.
Precondition (observational studies). Before proposing an analysis plan for an observational design (cohort, case-control, cross-sectional, registry, or survey), confirm that a literature-grounded variable operationalization exists — a variable_operationalization.md from /define-variables, or an equivalent codebook-backed definition table. If none exists, warn the user and recommend running /define-variables first, so exposure / outcome / covariate definitions and cutoffs are citation-backed rather than invented ad hoc from the data dictionary (ad-hoc phenotype/cutoff definitions are a common reviewer-rejection trigger for observational work — see the dictionary-first discipline). This is a WARN, not a hard block: proceed on explicit user confirmation, recording that the operationalization artifact was not available. For stricter projects, treat the missing artifact as a hard stop until /define-variables has run. (This mirrors the same precondition already enforced in /write-protocol before drafting Methods.)
Based on the data structure and research question, propose an analysis plan:
A predictor that perfectly predicts the outcome breaks maximum likelihood: no finite MLE exists. The failure is silent — glm does not error, it returns an odds ratio near 0 (or enormous), p ≈ 0.99, and an AUC that then gets written into a table. This is routine in diagnostic imaging, because the good signs are the pathognomonic ones (T2-FLAIR mismatch, the string sign, a halo sign): 100% specificity means an empty cell by construction.
bash python3 "${CLAUDE_SKILL_DIR}/scripts/check_separation.py" \ --data cohort.csv --outcome idh_mutant --auto --strict
COMPLETE_SEPARATION (an empty cell) and QUASI_SEPARATION (a cell below the sparsity floor) both halt the plan. The remedy is a design decision, not a numerical one: Firth's penalised likelihood keeps one model, while a two-stage rule — classify the sign-positive cases directly, model only the sign-negative remainder — is usually the clinically meaningful choice for a pathognomonic sign, because a sign-positive patient is already diagnosed and the real question is what to do with everyone else. Decide this in the plan; do not discover it in the output.
Present the plan and wait for user approval before executing.
| Type | When to use | Python packages | R packages | Primary output | |------|-------------|-----------------|------------|----------------| | Table 1 (Demographics) | Baseline characteristics | pandas, scipy | tableone | Demographics table | | Diagnostic Accuracy | Sensitivity/specificity/AUC | sklearn, scipy | pROC | ROC curve, performance table | | Inter-rater Agreement | Multiple raters rating same items | krippendorff, pingouin | irr, psych | ICC/Kappa table | | Meta-analysis | Pooling effect sizes across studies | -- | meta, metafor | Forest + funnel plots | | DTA Meta-analysis | Pooling diagnostic accuracy across studies | -- | meta, metafor, mada | SROC + paired forest plots | | Survey/Likert | Ordinal rating scales | pingouin, scipy | psych | Descriptive + reliability | | Survival | Time-to-event outcomes | lifelines | survival | KM curves, Cox table | | Group Comparison | Comparing 2+ groups | scipy, pingouin | -- | Test results + effect sizes | | Correlation | Association between variables | scipy, pingouin | -- | Scatter + correlation matrix | | Logistic Regression | Binary outcome + predictors | statsmodels, sklearn | -- | OR table, C-statistic, forest plot | | Linear Regression | Continuous outcome + predictors | statsmodels | -- | Coefficient table, R², diagnostic plots | | Propensity Score | Observational treatment comparison | sklearn, statsmodels | MatchIt, WeightIt, cobalt | Balance table, Love plot, weighted analysis | | Survey-Weighted | Complex survey data (KNHANES, NHANES, KCHS) | statsmodels | survey, tableone, gWQS | Weighted Table 1, wOR table, subgroup results | | Repeated Measures | Longitudinal / multi-timepoint data | pingouin, statsmodels | lme4, nlme, geepack | Spaghetti plot, LMM/GEE/RM ANOVA results |
For Logistic Regression, Linear Regression, Propensity Score, Survey-Weighted, and Repeated Measures: load the corresponding guide from ${CLAUDE_SKILL_DIR}/references/analysis_guides/ before generating code. For Survey-Weighted analysis, also load survey_weighted.md. For NHIS claims-based studies, load nhis_icd10_mapping.md. For test selection guidance, load ${CLAUDE_SKILL_DIR}/references/analysis_guides/test_selection.md.
Generate and run a Python (preferred) or R script following these rules:
Every script MUST start with a reproducibility header:
python""" Analysis: {description} Date: {YYYY-MM-DD} Random seed: 42 Python: {version} Key packages: {package==version, ...} """ import numpy as np import pandas as pd np.random.seed(42)
np.random.seed(42) or set.seed(42).python import matplotlib.pyplot as plt style_path = os.path.join(os.environ.get('CLAUDE_SKILL_DIR', '.'), 'references/style/figure_style.mplstyle') if os.path.exists(style_path): plt.style.use(style_path)
user-specified output directory.
Before running parametric tests, always check and report:
sum(n per stratum) == unique N and sum(events per stratum) == total events. A trend test on overlapping or non-exhaustive strata is invalid. Emit the per-stratum N/event table and the reconciliation in the output (this is the analysis-side mirror of /self-review check_cohort_arithmetic.py PARTITION_OVERLAP).max(0, lower); a zero-event Wilson/score interval can emit a negative or absurd tiny-exponent lower bound (e.g., 3.47e-16) that is a display artifact, not a real bound. Report 0 (or 0.0%) instead, and prefer an exact (Clopper-Pearson) interval for zero/near-zero cells.After all analyses complete, save _analysis_outputs.md in the output directory. Use the output format and bound binary workflow when producing the analysis outputs.
This manifest enables downstream skills (/make-figures, /write-paper) to auto-discover analysis outputs without user intervention.
For prespecified binary predictions on independent units, use the bundled scripts/run_analysis.py run workflow described in references/analysis_run_workflow.md. It executes the existing diagnostic template and embeds data/configuration/code/ output hashes, exact counts, metric-specific denominators and the reproduction command in this same manifest. audit checks recorded versions without rewriting them; compare separates declared context and recorded numeric equality from byte drift. It does not select thresholds or establish study validity, privacy clearance or reuse rights. The original synthetic example runs with python3 ${CLAUDE_SKILL_DIR}/scripts/demo_analysis_run.py --out demo-project.
Before reporting any script as final, lint every emitted .py/.R file for the reproducibility-hygiene "slop" that AI-generated analysis code recurrently carries:
bashpython3 ${CLAUDE_SKILL_DIR}/scripts/check_generated_code.py {script.py} --strict # or scan a whole output directory: python3 ${CLAUDE_SKILL_DIR}/scripts/check_generated_code.py --code-dir {analysis_dir} --strict
Major findings (fix before reporting the script):
MISSING_SEED — randomness used (sampling, bootstrap, train/test split, rng) with nonp.random.seed / set.seed / random_state= / default_rng. Non-reproducible.
HARDCODED_DATA_LITERAL — a hand-typed, table-shaped numeric literal instead ofread_csv()/read.csv() + subset. This is the data-integrity rule "never hand-type CSV data into scripts."
HARDCODED_ABS_PATH — an absolute path literal (/Users/, /home/, C:\, ~/Documents).Non-portable and a PII risk.
INPLACE_SOURCE_OVERWRITE — writing to the same path read as input; this overwrites rawdata. Write derived outputs to a new path ("never modify raw data").
Flags (fix when tidying): DEBUG_LEFTOVER (a breakpoint() / browser() / debug print / TODO marker left in) and UNUSED_IMPORT (a dead Python dependency).
The gate is conservative on the Major checks — it fires HARDCODED_DATA_LITERAL only on genuinely table-shaped literals and MISSING_SEED only on a real randomness call — so it stays quiet on legitimate analysis code. It is the analysis-side mirror of the data-integrity and reproducibility checks /self-review is built to catch downstream.
After execution, generate manuscript-ready text:
the Methods section.
These rules apply to ALL analyses without exception:
Exception: report as p < 0.001 when the value is below 0.001.
risk ratio, etc., as appropriate).
Report the assumption test results.
performing 3+ comparisons.
appropriate precision for the measurement.
effect (MDE), a-priori or post-hoc power, or required sample size that will appear in the manuscript MUST be emitted by this committed script — printed with its method and inputs (n per arm, alpha, power, allocation ratio, one/two-sided) — not computed in a side tool (GPower, an online calculator) and pasted in. Use one method family consistently (e.g. the exact noncentral-t via statsmodels TTestIndPower or scipy's nct); do not mix a normal approximation for some values with exact-t for others. A value that exists only in the manuscript with no script that reproduces it is the failure mode /self-review Phase 2.5a-2 is built to catch.
estimands (T25, median time-to-event), pooled proportions, and subdistribution HRs, not just ORs/HRs/AUCs — MUST be emitted together with its 95% CI. In the output CSV, carry the interval as explicit columns (estimate, ci_lower, ci_upper) or as a single text column in est (lo–hi) form; never emit a point estimate with no interval in an adjacent column. Round ORs/HRs/sHRs to 2 decimals and AUC/C-statistic to 3. This is the output side of the /self-review §C assertion that "all primary metrics have 95% CIs."
Whenever a primary result is a correlation, a standardized coefficient, a regression slope, an OR/HR/RR, or a Cohen's d, also report it as a plain-language unit shift a non-statistician can act on. The coefficient answers "is there an association"; the translation answers "how much, in units I use". This complements rule 3 above (report effect sizes) — it does not replace it.
When to apply
or a standardized slope.
Procedure
(IQR). State both endpoints in native units.
monotonic-linear assumption: delta_outcome ~= ((x_p75 - x_p25) / SD_x) * |rho| * SD_outcome. Report as: "going from {x_p25} to {x_p75} {units} is associated with about {delta_outcome} {outcome units} on average."
delta_outcome = b * (x_p75 - x_p25) (cleaner; no monotonicity caveat).SD-scaled one.
the absolute risk difference, and NNT = 1 / ARR (or NNH = 1 / ARI). Always state the baseline risk used.
causation from a crude or unadjusted estimate.
Worked example (synthetic) rho = 0.39 between a fasting marker (IQR 0.6 to 3.5 units, SD 3.05) and an index (SD 2.13): ((3.5 - 0.6) / 3.05) * 0.39 * 2.13 ~= 0.8 -> "Going from the 25th to the 75th percentile of the marker is associated with about 0.8 index units higher on average (monotonic-linear approximation; crude, unadjusted)."
Output contract (clinical-utility is a default, not an optional add-on). Report every primary effect in units a clinician acts on, by default — do not leave these as prose to be added later:
a stated baseline + absolute risk difference + NNT (or NNH = 1/ARI), baseline risk explicit. A relative-only headline is incomplete.
beneath the effect size.
net-benefit pass at the relevant threshold is standard output, not just AUC + calibration. An incremental claim reports added net benefit / NRI / IDI over the established clinical model, not the new model's AUC alone. See references/table-standards/table-types/incremental_value.md and the make-figures decision_curve exemplar (and render_core_figures.py for the rendered curve).
(missing package, data format mismatch, wrong column name), and present a fix.
install.packages() and wait for user confirmation.or calibration slope/intercept) alongside discrimination metrics. AUC alone is insufficient.
Before generating any publication table, load the journal profile and table type template:
${CLAUDE_SKILL_DIR}/references/table-standards/journal-profiles/{journal}.yaml if a target journal is known${CLAUDE_SKILL_DIR}/references/table-standards/table-types/{type}.md for the relevant table typeOutput formats (always generate all three):
Universal rules (enforced regardless of journal):
Journal-specific parameters (from loaded YAML profile):
Footnote placement order (universal):
gtsummary pipeline (recommended for R table generation):
rtheme_gtsummary_journal("{journal}") # "jama", "lancet", "nejm" theme_gtsummary_compact() # ... build table ... tbl %>% as_flex_table() %>% flextable::save_as_docx(path = "table.docx")
Validation checklist (run before finalizing any table):
figure_style.mplstyle for consistent appearancereferences/templates/table1_demographics.pyreferences/table-standards/table-types/table1_demographics.mdtbl_summary() with journal theme for R pipelinereferences/analysis_guides/diagnostic_accuracy.md (load before generating code — every metric with a CI on a stated analysis unit; the confidence-weighted trap unweighted-baseline AUC + monotonic-encoding check, produce-side of probe D9]; paired DeLong vs MRMC for reader-generalising claims; per-stratum admissibility D10]; one-scale-per-comparison D11])references/templates/diagnostic_accuracy.pyreferences/table-standards/table-types/incremental_value.md (paired ΔAUC + DeLong CI, continuous NRI with event/non-event split, IDI, net benefit at a prespecified threshold, same-patient/calibrated-first discipline). Pairs the decision-curve exemplar make-figures references/exemplar_plots/decision_curve.md.references/table-standards/table-types/reader_study.md (per-reader + reader-averaged AUC with an Obuchowski–Rockette/DBM reader+case CI, per-patient vs per-lesion unit, superiority vs non-inferiority margin). Use an MRMC method (not a fixed-reader DeLong CI) for a claim that generalises to readers. Pairs make-figures references/exemplar_plots/mrmc_roc.md.references/analysis_guides/agreement_reliability.md (load before generating code — the pseudoreplication trap for clustered/repeated measurements + the pseudoreplication-safe per-subject / mixed-effects code, ICC model/type selection, agreement-vs-reliability distinction; pairs with self-review probe O18)references/table-standards/table-types/agreement.md (ICC with model/type + CI, weighted κ for ordinal, Bland–Altman bias + LoA, reliability-vs-agreement distinction, common errors)references/templates/agreement_analysis.pymetabin() for binary outcomes (OR/RR), metagen() for continuousmethod = "Inverse", method.tau = "DL", method.random.ci = "HK"comb.fixed → common, hakn → method.random.cimetaprop() with sm = "PLOGIT", method.ci = "CP"k >= 10 (note underpowered otherwise)tau-squared on the logit scale and a 95% prediction interval (metaprop(..., prediction = TRUE)) in addition to the pooled estimate; the PI conveys where a future study's proportion is expected to fall under the random-effects modelmetainf())update(res, subgroup = variable)references/templates/dta_meta_analysis.Rmada, meta, metafor packages) for DTA meta-analysismada::reitsma() — recommended over separate pooling of Se/Spmetabin() for comparative studies (OR/RR)metaprop() with sm = "PLOGIT" for single-arm pooled proportionmethod = "Inverse", method.tau = "DL", method.random.ci = "HK"mada unavailable, use metafor::rma.mv() with bivariate structureanalysis_guides/network_meta_analysis.md before generating codenetmeta (frequentist: netsplit, decomp.design, netheat, netrank P-scores, comparison-adjusted funnel) or Bayesian gemtc / multinma / BUGSnet (node-split, SUCRA, DIC)network_meta_analysis.mdanalysis_guides/health_economic_evaluation.md before generating codeheemod / dampack / hesim / BCEA (state-transition + PSA + CEAC + EVPI), flexsurv for survival extrapolation. Report against CHEERS 2022; make the "cost-effective" conclusion conditional on a stated willingness-to-pay threshold. Review-side probes: HE1–HE8 in health_economic_evaluation.md(min+max) - x before computing the scale total or Cronbach's alpha. An un-recoded reverse item produces a negative item-rest correlation and a negative alpha — which is a coding bug, not evidence of a multidimensional construct (do not defend it as such; you lose a review round). likert_summary.py prints the per-item item-rest correlations, flags negative ones as reverse-code suspects, warns loudly on a negative alpha, and accepts --reverse-items E3 ... to apply the recode before scoring. To screen at cleaning time, run /clean-data scripts/check_reverse_coding.py. See the global rule survey-scale-reliability.md.references/analysis_guides/survival.md (load before generating code — competing risks first naive 1−KM overestimates → produce the Aalen–Johansen/Fine–Gray CIF; cause-specific vs subdistribution for which question, produce-side of probe S3]; PH check → RMST when violated; reverse-KM follow-up + C-index variant S6]; estimand provenance S8])references/table-standards/table-types/survival_results.md (Cox results table: events/person-time, reverse-KM median follow-up, univariable + adjusted HR with CI, PH-assumption footnote, EPV/sparse-stratum and RMST-when-PH-violated rules)events / n_covariates >= 10 before fitting Cox (mirror of the logistic EPV rule). Warn if violated and fall back to a Firth/penalized Cox or profile-likelihood CIs; do not report Wald CIs from a sparse-event model as if stablecoxph(..., cluster = id) / robust = TRUE in R, cluster_col= in lifelines, e.g. survival_analysis.py --cluster <id>). Treating correlated rows as independent understates the standard errors and narrows the CI artificiallytt() time-transform), or switch to RMST difference at a fixed horizon, and state the violation explicitlyquantile() from the KM/survfit object and always emit the 95% CI (the lower/upper from quantile(km, conf.int=TRUE), or a log-transformed / bootstrap CI) alongside the events/n that define it. A quantile point estimate reported without its CI is incomplete. If the event rate is below the target quantile, report "not reached" and consider Weibull parametric extrapolation (also with an interval)When exact event times are unknown (e.g., health screening cohorts where status changes are detected at periodic visits), standard KM underestimates time-to-event. Use interval-censored methods:
icenReg (parametric/semi-parametric IC regression), interval (NPMLE/Turnbull), survival (Surv type "interval2")icenReg::ic_par(). Report shape/scale parameters and compare AIC across distributionscoxph() on visit-dated events as if the times were exactmsm), account for subject-level clustering with a subject random effect or a sandwich (robust) variance, and check the time-homogeneity assumption (constant transition intensities) before trusting a single rateWhen death or other events preclude the outcome of interest, standard KM overestimates cumulative incidence (treats competing events as censored). Use competing risk methods:
cmprsk (Fine-Gray), tidycmprsk (tidy interface), survival (cause-specific Cox)cmprsk::cuminc() — replaces 1-KM for each event type. Gray's test for group comparisoncmprsk::crr() or tidycmprsk::crr() — reports subdistribution HR (sHR) with 95% CI. Interpretable as effect on CIF directly. Check the subdistribution-PH assumption the same way you check it for Cox (a time-interaction term on the subdistribution scale, or inspection of scaled-residual analogues); a constant sHR is an assumption, not a given. Report the cause-specific HR alongside it so the etiologic and prognostic readings are both visibleanalysis_guides/regression.md before generating codereferences/templates/regression.py (set regression_type = "logistic")references/analysis_guides/calibration.md (load before generating code for any model that outputs a risk used for a decision — the apparent slope of exactly 1.00 is the in-sample tell, so produce the bootstrap optimism-corrected slope/intercept; Van Calster's calibration levels; scaled Brier; why Hosmer–Lemeshow is dropped; produce-side of probe S7)cov_type="cluster", cov_kwds={"groups": id} in statsmodels) or a mixed-effects logistic model — a naive logit CI assumes independent rows and is too narrowanalysis_guides/regression.md before generating codereferences/templates/regression.py (set regression_type = "linear")analysis_guides/propensity_score.md before generating codereferences/templates/propensity_score.pyanalysis_guides/survey_weighted.md before generating codereferences/templates/survey_weighted_analysis.pysurvey package strongly recommended over Python for publicationanalysis_guides/mediation.md before generating codemediation / CMAverse / PROCESS); ≥2000 resamples, bias-corrected percentile CI — not the Sobel testCMAverse, regmedint), not the naive OR productinteractionR / epiR for RERI/AP/S with CIs; follow Knol & VanderWeele interaction-reporting recommendations. Review-side probe: O14 in observational_confounding.mdanalysis_guides/multiplicity.md before generating codem (the denominator), applied to the whole tested set — never shrink m to the winnerspoolr::meff()); a univariate hit may be a marker for a correlated cause (consider WQS / quantile g-computation / BKMR before causal reading)survey_weighted.md) WITH the correction. Review-side probe: O17 in observational_confounding.mdanalysis_guides/mendelian_randomization.md before generating codeTwoSampleMR / MendelianRandomization)coloc) + positive control + adverse-effect phenome scan. Non-linear MR: residual/doubly-ranked shapes can be artefactual → require negative/positive controls + extreme-stratum sensitivitymendelian_randomization.mdanalysis_guides/polygenic_risk_score.md before generating codebigsnpr), PRS-CS / PRS-CSx, BridgePRSpolygenic_risk_score.mdanalysis_guides/nhis_icd10_mapping.md for disease definition patternsanalysis_guides/burden_decomposition_forecasting.md before generating code/check-reporting); keep burden/attribution/decomposition/forecast descriptive or associational unless a causal design (natural experiment, MR — analysis_guides/mendelian_randomization.md) is in placeanalysis_guides/repeated_measures.md before generating codereferences/templates/repeated_measures.pyanalysis_guides/missing_data.md and apply MICE before analysisApplies to any multivariable adjustment (logistic / linear / Cox / propensity-score / survey-weighted). Two coupled failure modes around a dose/duration variable anchored to a categorical exposure (pack-years under smoking status, grams/week under alcohol use, cessation-duration under former-smoker):
pack_years is a structural zero, not missing-at-random — the value is known to be 0 by definition of the category. Feeding it to MICE/MNAR imputation as if it were missing fabricates a non-zero dose for unexposed subjects and corrupts the exposure contrast. Before imputing any dose/duration column, set the implied zero explicitly (IF status == 'never' THEN dose = 0) and impute only the genuinely-missing residual among the exposed. /clean-data flags categorical-implied-zero contradictions (a never row with a NULL dose) and ships scripts/check_structural_zero.py.Applies to any cross-sectional / single-visit outcome regression (the exposure and outcome are measured at one time point, so temporal order is not observed). The selection rule is causal, not statistical:
[VERIFY: variable_name] and ask the user to confirm against the data dictionary./search-lit for all citations.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 42,399 | 14,702 | -65% | 1 | 1 | 0% | 8,290 | 15,592 | +88% | 0 | 0 | — |
case-02 | fail→fail | 8,505 | 45,393 | +434% | 1 | 1 | 0% | 425 | 15,337 | +3509% | 0 | 0 | — |
case-03 | fail→fail | 12,492 | 11,633 | -7% | 1 | 1 | 0% | 675 | 15,394 | +2181% | 0 | 0 | — |
case-04 | pass→pass | 18,839 | 14,379 | -24% | 1 | 1 | 0% | 3,047 | 16,148 | +430% | 0 | 0 | — |
case-05 | pass→pass | 15,681 | 17,702 | +13% | 1 | 1 | 0% | 2,352 | 16,570 | +605% | 0 | 0 | — |
case-06 | fail→pass | 14,754 | 13,089 | -11% | 1 | 1 | 0% | 2,213 | 16,943 | +666% | 0 | 0 | — |
case-07 | pass→fail | 16,677 | 11,037 | -34% | 1 | 1 | 0% | 2,788 | 15,510 | +456% | 0 | 0 | — |
case-08 | pass→pass | 12,773 | 9,513 | -26% | 1 | 1 | 0% | 1,899 | 15,979 | +741% | 0 | 0 | — |
case-09 | pass→fail | 14,834 | 11,055 | -25% | 1 | 1 | 0% | 2,628 | 15,439 | +487% | 0 | 0 | — |
case-10 | pass→pass | 16,363 | 9,778 | -40% | 1 | 1 | 0% | 2,285 | 16,464 | +621% | 0 | 0 | — |
case-11 | fail→pass | 28,703 | 17,829 | -38% | 1 | 1 | 0% | 2,086 | 17,997 | +763% | 0 | 0 | — |
case-12 | pass→pass | 21,205 | 13,824 | -35% | 1 | 1 | 0% | 3,504 | 17,321 | +394% | 0 | 0 | — |
case-13 | pass→pass | 18,062 | 12,726 | -30% | 1 | 1 | 0% | 2,887 | 16,032 | +455% | 0 | 0 | — |
case-14 | pass→pass | 14,090 | 25,800 | +83% | 1 | 1 | 0% | 2,166 | 18,845 | +770% | 0 | 0 | — |
case-15 | fail→pass | 8,395 | 6,400 | -24% | 1 | 1 | 0% | 1,162 | 15,813 | +1261% | 0 | 0 | — |
case-16 | fail→pass | 17,042 | 14,608 | -14% | 1 | 1 | 0% | 2,704 | 17,360 | +542% | 0 | 0 | — |
case-17 | fail→fail | 13,400 | 7,894 | -41% | 1 | 1 | 0% | 2,202 | 16,059 | +629% | 0 | 0 | — |
case-18 | pass→pass | 12,333 | 10,253 | -17% | 1 | 1 | 0% | 1,801 | 16,415 | +811% | 0 | 0 | — |
case-19 | fail→fail | 8,946 | 12,430 | +39% | 1 | 1 | 0% | 1,441 | 15,272 | +960% | 0 | 0 | — |
case-20 | fail→fail | 15,710 | 17,555 | +12% | 1 | 1 | 0% | 2,430 | 17,459 | +618% | 0 | 0 | — |
case-21 | fail→fail | 40,020 | 20,122 | -50% | 1 | 1 | 0% | 7,862 | 18,296 | +133% | 0 | 0 | — |
case-22 | fail→fail | 26,586 | 29,923 | +13% | 1 | 1 | 0% | 4,895 | 20,823 | +325% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +9 percentage points is the difference between those two pass rates over the 16 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/27/2026 | -23% |
Other measured skills in the registry, with their headline benchmark lift.