Code
sm_a <- \(qt) pick(res_items$qtype_summary, mean_age_slope, question_type == qt)
g_en <- filter(gg, sample == "en-US")
q3_rng <- rng(q3_qt$within_minus_between, 3)
jt <- tribble(
~source, ~claim, ~june, ~now, ~status,
"stories_tom §2", "Story-construct schemes explain little item difficulty; question type dominates",
"R² ≈ .07–.11 (schemes)",
glue("question type R² {n2(k$r2_qt)}; old group {n2(k$r2_og)}; new construct {n2(k$r2_nc)}"),
"survives",
"stories_tom §2", "False-belief targets carry the age signal; controls are flat",
"boxplot; schemes R² ≈ .06 (n.s.) for age",
glue("above the guessing floor, FB {n2(k$fl_fb, 3)} vs controls {n2(k$fl_rc, 3)} logit/yr (difference {n2(k$fl_diff, 2)} [{n2(k$fl_lo, 2)}, {n2(k$fl_hi, 2)}]); raw logit slopes {n2(sm_a('false_belief'), 3)} vs {n2(sm_a('reality_check'), 3)} (difference {n2(k$raw_diff, 2)} [{n2(k$raw_lo, 2)}, {n2(k$raw_hi, 2)}]); 2PL slopes {n2(k$a_fb)} vs {n2(k$a_rc)}"),
"survives on the chance-corrected scale (raw logit slopes do not separate them; controls also flat because at ceiling)",
"stories_tom §3", "Controls correlate moderately with targets, weakly with age",
"r = .46 and .27 (pooled)",
glue("pooled {n2(k$r_ct_pooled)} / {n2(pick(cc, r_control_age, method == 'pooled over runs (June method)', item_set == 'policy items dropped'))}; within dataset × form {n2(k$r_ct_within)} / {n2(pick(cc, r_control_age, method == 'within dataset x form, Fisher-pooled', item_set == 'policy items dropped'))}"),
"survives with changes (pooled r reproduces; within a site it is lower)",
"stories_tom §3", "Controls do not gate target age sensitivity",
"similar target~age slopes after pass and fail",
glue("June method {n2(pick(gj, target_age_beta_perSD, !ctrl_pass), 3)} vs {n2(pick(gj, target_age_beta_perSD, ctrl_pass), 3)}/SD; GLMM interaction de-DE {n2(g_de$interaction, 2)} (p {pe(g_de$interaction_p)}), en-US {n2(g_en$interaction, 2)} (p = {n2(g_en$interaction_p, 3)}), es-CO {n2(g_co$interaction, 2)} (p = {n2(g_co$interaction_p, 2)})"),
"partly overturned (gating in de-DE and en-US, not in es-CO; descriptive)",
"stories_tom §3", "Dropping controls lowers reliability; keep them",
"marginal .92 → .89",
glue("June method {n2(rrow(jn_s, 'all items', 'Rasch', marginal_rxx_mirt), 3)} → {n2(rrow(jn_s, 'targets only', 'Rasch', marginal_rxx_mirt), 3)}; empirical Leipzig {n2(rrow(de_s, 'all items', 'Rasch', empirical_rxx), 3)} → {n2(rrow(de_s, 'targets only', 'Rasch', empirical_rxx), 3)}; UTDT {n2(rrow(ar_s, 'all items', 'Rasch', empirical_rxx), 3)} → {n2(rrow(ar_s, 'targets only', 'Rasch', empirical_rxx), 3)}"),
"survives with changes (direction holds; the magnitudes were model-implied)",
"stories_tom §5; tom_dimensionality §1", "Not cleanly unidimensional",
"ev1/ev2 ≈ 1.9 (Leipzig)",
glue("Leipzig {n2(k$ev_de)}; Western/Bogotá/es-AR {rng(k$ev_other)}; ECV {k$ecv}, omega-h/omega-t {rng(ld$omega_h / ld$omega_total)}"),
"survives with changes (Leipzig and es-AR; one score defensible elsewhere)",
"tom_dimensionality §1", "Parallel analysis's 11 factors are over-extraction",
"11 factors",
glue("June method {rng(res_dim$eigen$pa_june_nfact, 0)} factors; resampled {rng(res_dim$eigen$pa_resample_ncomp[res_dim$eigen$sample %in% dim_primary], 0)} components, {rng(res_dim$eigen$pa_resample_nfact[res_dim$eigen$sample %in% dim_primary], 0)} factors"),
"survives (parallel analysis is uninformative here either way)",
"tom_dimensionality §2", "Question type organizes covariance; story weakly; constructs not at all",
"within − between: .101 / .039 / .045 (table)",
glue("tetrachoric: question type {rng(qt_contrast, 3)}; story {rng(st_contrast, 3)}; construct {rng(nc_contrast, 3)}. Q3 residuals: question type {q3_rng}, story {rng(q3_st$within_minus_between, 3)}"),
"partly overturned (the tetrachoric pattern reproduces but partly reflects shared difficulty; on Q3 residuals question type groups items only in some samples)",
"tom_dimensionality §2", "Two-factor EFA gives no clean sub-construct",
"factor r .19, 28% variance",
glue("factor r {rng(res_dim$efa2_summary$factor_r[res_dim$efa2_summary$sample %in% dim_primary])}; second factor differs by sample"),
"survives",
"tom_dimensionality §3", "A false-belief-only scale is less reliable and no more age-valid",
"Rasch rxx .605 vs .842; age r .401 vs .402",
glue("Leipzig alpha {n2(pick(res_dim$subscales, alpha, sample == 'de_ib', scale == 'false-belief only'), 3)} vs {n2(pick(res_dim$subscales, alpha, sample == 'de_ib', scale == 'all items'), 3)}; es-AR age r {n2(pick(res_dim$subscales, age_r, sample == 'ar_nhb', scale == 'false-belief only'), 3)} vs {n2(pick(res_dim$subscales, age_r, sample == 'ar_nhb', scale == 'all items'), 3)}"),
"survives",
"tom_dimensionality synthesis", "ToM is a reliable composite",
"reliability .92",
glue("the .92 is model-implied for a {jp$items_in_model}-item pool ({n2(jp$rasch_marginal_rxx_june_method, 3)}); empirical {n2(jp$rasch_empirical_rxx_eap, 3)}; single fixed forms {k$rel_forms}; fCAT {k$rel_fcat}"),
"overturned",
"tom_dimensionality synthesis", "Inter-item correlations are uniformly low",
"≈ .13",
glue("June-style rebuild {n2(pick(res_dim$eigen, mean_offdiag_r, sample == 'de_ib_junelike'), 3)}; cleaned {rng(res_dim$eigen$mean_offdiag_r[res_dim$eigen$sample %in% dim_primary], 3)}"),
"survives with changes",
"tom_dimensionality caveat", "Story testlet effect is real but weak; a bifactor model is risky",
"not fitted",
glue("story bifactor better by AIC in all samples; information overstated {k$info_over}; θ r {k$cor_uni_g}"),
"new (confirms 'weak')",
"tom_dif_multigroup", "Scalar invariance is rejected with controls in",
"χ²/df ≈ 29; BIC prefers configural by ≈ 580",
glue("release-equivalent June design {n2(jbv('J_release', 'all', X2_df), 1)}, dBIC {round(jbv('J_release', 'all', dBIC))}; corrected June design dBIC {round(jbv('J_policy', 'all', dBIC))}; A χ²/df {n2(k$A_scal_x2df, 1)}, Rasch dBIC {n2(tr_('A', 'scalar vs configural', dBIC), 0)}, 2PL dBIC {n2(t2('A', 'scalar vs metric', dBIC), 0)}, floor-0 rule dBIC {n2(tr_('A_g0', 'scalar vs configural', dBIC), 0)}; B χ²/df {n2(k$B_scal_x2df, 1)}, dBIC {n2(tr_('B', 'scalar vs configural', dBIC), 0)} / {n2(t2('B', 'scalar vs metric', dBIC), 0)}"),
"partly overturned (holds in June's design and in stories 13–18; in stories 1–6 BIC rejects only under the floor-0 guessing rule)",
"tom_dif_multigroup; stories_tom §4", "Controls are the dominant source of cross-language non-invariance",
"mean |DIF| ≈ 1.9 (controls) vs ≈ 0.5 (targets)",
glue("release-equivalent {n2(pick(dbt, mean_abs_db, analysis == 'J_release', kind == 'control'))} vs {n2(pick(dbt, mean_abs_db, analysis == 'J_release', kind == 'target'))}; corrected June design {n2(pick(dbt, mean_abs_db, analysis == 'J_policy', kind == 'control'))} vs {n2(pick(dbt, mean_abs_db, analysis == 'J_policy', kind == 'target'))}; A Rasch {n2(dmv('A', 'control', rasch_s2))} vs {n2(dmv('A', 'target', rasch_s2))}, 2PL {n2(dmv('A', 'control', twopl_purified))} vs {n2(dmv('A', 'target', twopl_purified))}; B Rasch {n2(dmv('B', 'control', rasch_s2))} vs {n2(dmv('B', 'target', rasch_s2))}, 2PL {n2(dmv('B', 'control', twopl_purified))} vs {n2(dmv('B', 'target', twopl_purified))}"),
"partly overturned (model- and design-dependent; the gap shrank)",
"tom_dif_multigroup", "Targets are comparable; false-belief and emotion DIF is small",
"mean |DIF| ≈ 0.5",
glue("false belief flagged {fb_A$n_flagged}/{fb_A$n_items} (A), {fb_B$n_flagged}/{fb_B$n_items} (B); story 13 FB es-AR {n2(k$acc_13_ar, 3)}; within es-AR across sites {wl_f('X_esAR')}/{wl_n('X_esAR')} items flagged"),
"overturned (but language is confounded with age, exposure and site)",
"tom_dif_multigroup", "Partial scalar invariance is achievable",
"p ≈ .8 (targets)",
glue("A p = {n2(k$A_part_p)} ({pick(res_inv$anchors, n_anchors, analysis == 'A')} anchors); B p = {n2(k$B_part_p)} ({pick(res_inv$anchors, n_anchors, analysis == 'B')} anchors); without V0 p = {n2(tr_('A_noV0', 'partial scalar vs configural', p), 4)}"),
"survives descriptively (anchors chosen on the same data; rejected without V0)",
"tom_dif_multigroup", "The invariant anchors are mostly false-belief and emotion targets",
"anchor set of targets",
glue("anchors include {anc$ctrl_anchor[anc$analysis == 'A']}/{anc$ctrl[anc$analysis == 'A']} controls (A) and {anc$ctrl_anchor[anc$analysis == 'B']}/{anc$ctrl[anc$analysis == 'B']} (B); DIF below ≈ {n2(k$mdd_med, 1)} logits is not detectable"),
"survives with changes",
"tom_reality_check_bug", "The 4 provable defects are inverted keys (CO moral rc_1, CO reference, late-DE deception rc_2/3)",
"below chance, site-specific",
glue("story 2 rc_1 {n2(k$s2rc1_2e, 3)} on V0 2e only (cause undetermined); story 4 rc_2/3 {n2(k$s4rc2_4g, 3)}/{n2(k$s4rc3_4g, 3)} on image 4g (rc_3 below chance in every language, rc_2 in de-DE and en-US; the key conflicts with the image; flipped r {n2(fc(rc2, 'flagged: 4g', r_ir_flipped))}/{n2(fc('tom_story4_deception_reality_check_3', 'flagged: 4g', r_ir_flipped))}); reference {n2(k$rr5, 3)}/{n2(k$rr11, 3)}/{n2(k$rr17, 3)}, below chance except German story 5 (design)"),
"partly overturned (the cells are broken, but not site-specific and not all key inversions)",
"tom_reality_check_bug", "Repairing the defects removes ≈ 70% of scalar non-invariance",
"χ² 702 → 212",
glue("{big(round(jbv('J_release', 'all', X2)))} → {big(round(jbv('J_policy', 'all', X2)))} ({spct(jbv('J_policy', 'all', X2_change_vs_release))}); controls {spct(jbv('J_policy', 'controls', X2_change_vs_release))}; PR #27 alone {spct(jbv('J_corrected', 'all', X2_change_vs_release))}"),
"different mechanism (about half, from exclusions, not key flips)",
"tom_reality_check_bug; README", "The 12 hand-flagged items are essentially a complete catalog of defects",
"all 12 map onto defects",
glue("{k$v_un} of {k$v_all} story-level items un-excluded; {k$v_keep} keep; {k$v_scop} scoped; {k$v_es} held for the translation check"),
"overturned",
"stories_tom §1", "Fixing the scoring bug raised Leipzig test–retest",
"≈ .45 → ≈ .53",
glue("first two runs {n2(pick(sf2, r, version == 'analysis'), 3)} (released {n2(pick(sf2, r, version == 'released v2_3'), 3)}; release-equivalent refit {n2(pick(sf2, r, version == 'release-equivalent refit'), 3)}); 60–180 d {n2(k$stab_60)}; > 300 d {n2(pick(sb, r, dataset == 'pilot_mpieva_de_main', gap_bin == '[300,Inf)', version == 'analysis'))}"),
"not replicated (the corrections do not raise it; alternate forms, months apart)",
"stories_tom §6", "Parallel retest items are broadly similar in difficulty",
"within-family SD ≈ 0.9 vs 2.3",
"not re-tested",
"not re-tested"
)
knitr::kable(jt, col.names = c("June source", "Claim", "June (quoted)", "Now (2026-09 data)", "Status"))