Skip to contents

1 Beyond familiarity: two process models

The confidence-rating SDT model treats recognition as a single continuous process: an item generates a sample of memory strength (or familiarity), and the observer maps that one number onto an ordered confidence scale. A persistent finding in recognition memory is that the resulting ROC is asymmetric — on z-transformed axes its slope is below one. The core SDT article reads that asymmetry as unequal variance: the old-item distribution is simply wider than the new-item distribution.

Unequal variance is not the only explanation. Two influential models keep the familiarity process but add a second process that also leaves its mark on the ROC:

  • Dual-process SDT (Yonelinas 1994) adds a recollection process: besides graded familiarity, an item can be consciously recollected, which supports a confident, all-or-none response. Recollection is one of the two standard accounts of the recognition ROC’s shape, the other being unequal variance (Wixted and Mickes 2010; Yonelinas 2024).
  • Meta-d′ (Maniscalco and Lau 2012) adds a metacognitive read-out: it asks how well an observer’s confidence tracks whether their decision was actually correct, separately from how well they discriminate old from new.

Both are versions of the same rating model — they consume identical data (counts per confidence category, with a 0/1 stimulus column) and reduce to the standard model when their extra parameter is switched off. They are selected with the version argument of sdt_rating():

version extra parameter(s) captures reduces to standard when
"standard" (default) — familiarity / strength only always
"dpsdt" Ro, Rn recollection of old items / recall-to-reject (Rn) of new items Ro, Rn → 0
"metad" logmratio metacognitive efficiency (log M-ratio) logmratio = 0

This article assumes the core SDT article: the four-step fitting workflow, the standard rating model, confidence thresholds, and the roc_sdt() / latent_sdt() / sdt_thresholds() / pp_check() toolkit. We focus here on what the second process adds — and because both versions are plain bmm models, everything from that workflow (hierarchical formulas, priors, post-processing) carries over unchanged.

2 Dual-process SDT

2.1 The model

Dual-process theory holds that a recognition decision can draw on two separable sources (Yonelinas 1994; the description here follows Wixted and Mickes 2010). Familiarity is a graded signal-detection process: old and new items generate overlapping Gaussian evidence, exactly as in the standard model. Recollection is a high-threshold process: with some probability the observer retrieves specific details that settle the decision with high confidence, and otherwise recollection fails and they fall back on familiarity.

bmm parameterizes recollection with two probabilities, both on the logit scale:

  • Ro — recall-to-accept: the probability \(\mathrm{logit}^{-1}(\texttt{Ro})\) that an old item is recollected as old, producing the most-confident “old” rating.
  • Rn — recall-to-reject: the probability \(\mathrm{logit}^{-1}(\texttt{Rn})\) that a new item is recollected as new (its absence from the studied set is recollected), producing the most-confident “new” rating.

The classic dual-process model of long-term recognition has recollection for old items only (Wixted and Mickes 2010). The two-sided version with a recall-to-reject term is the dual-process model that Yonelinas (2024) applies to visual working memory, where the threshold component carries both terms: in a single-probe test, the item held in memory rejects a changed probe as readily as it accepts an unchanged one, and in change detection with a whole-array probe it is recall-to-reject that recollection mainly supports. The probability of each confidence category is then a mixture: a recollection component that piles mass on the extreme category, and a \((1 - R)\)-weighted familiarity component spread across the scale by the thresholds.

Dual-process model. Old and new items generate equal-variance familiarity evidence (curves); on a fraction Ro of old trials recollection succeeds and the item is reported with maximal 'old' confidence (right spike), and on a fraction Rn of new trials recall-to-reject yields maximal 'new' confidence (left spike). The recollection mass sits on top of the familiarity process, not on the evidence axis.

Figure 2.1: Dual-process model. Old and new items generate equal-variance familiarity evidence (curves); on a fraction Ro of old trials recollection succeeds and the item is reported with maximal ‘old’ confidence (right spike), and on a fraction Rn of new trials recall-to-reject yields maximal ‘new’ confidence (left spike). The recollection mass sits on top of the familiarity process, not on the evidence axis.

Because recollection adds mass at the high-confidence ends, its fingerprint is a curved z-transformed ROC: a pure unequal-variance Gaussian produces a straight zROC (slope \(1/s\)), whereas a threshold component bends it (Yonelinas 2024). We return to this contrast below.

Ro and Rn are fixed off by default (a constant near \(-\infty\) on the logit scale, so recollection probability \(\approx 0\) and the model is exactly the standard rating model). You switch recollection on by adding it to the formula — Ro ~ 1 for the one-sided model (recollection of old items only) or Ro ~ 1, Rn ~ 1 for the two-sided model.

2.2 Worked example: recognition memory

We use the same Pratte et al. (2010) recognition data as the core article (from the roc6 collection in the MPTinR package): 97 subjects judging old and new items on a 6-point confidence scale.

stopifnot(requireNamespace("MPTinR", quietly = TRUE))
data("roc6", package = "MPTinR")
pratte <- roc6[roc6$exp == "Pratte_2010", ]

rating_data <- rbind(
  data.frame(id = pratte$id, stimulus = 1L,
             r1 = pratte$OLD_3new, r2 = pratte$OLD_2new, r3 = pratte$OLD_1new,
             r4 = pratte$OLD_1old, r5 = pratte$OLD_2old, r6 = pratte$OLD_3old),
  data.frame(id = pratte$id, stimulus = 0L,
             r1 = pratte$NEW_3new, r2 = pratte$NEW_2new, r3 = pratte$NEW_1new,
             r4 = pratte$NEW_1old, r5 = pratte$NEW_2old, r6 = pratte$NEW_3old)
)

The dual-process model attributes the ROC asymmetry to recollection, so we keep the familiarity process equal-variance (we do not estimate sdratio) and free both recollection terms:

model_dp <- sdt_rating(response = paste0("r", 1:6), stimulus = "stimulus",
                       version = "dpsdt")

fit_dp <- bmm(
  formula = bmf(d ~ 1 + (1 | id), criterion ~ 1 + (1 | id),
                spacing ~ 1, Ro ~ 1, Rn ~ 1),
  data = rating_data,
  model = model_dp,
  backend = "cmdstanr",
  cores = 4,
  chains = 4,
  iter = 7000,
  warmup = 1000,
  thin = 6,
  refresh = 0,
  silent = 2,
  file = "fits/bmmfit_sdt_dpsdt_vignette"
)
summary(fit_dp)
#>   Model: sdt_rating(response = paste0("r", 1:6),
#>                     stimulus = "stimulus",
#>                     version = "dpsdt") 
#>   Links: d = identity; criterion = identity; spacing = identity; sdratio = identity; Ro = identity; Rn = identity 
#> Formula: d ~ 1 + (1 | id)
#>          criterion ~ 1 + (1 | id)
#>          spacing ~ 1
#>          sdratio = 0
#>          Ro ~ 1
#>          Rn ~ 1 
#>    Data: rating_data (Number of observations: 194)
#>   Draws: 4 chains, each with iter = 7000; warmup = 1000; thin = 6;
#>          total post-warmup draws = 4000
#> 
#> Multilevel Hyperparameters:
#> ~id (Number of levels: 97) 
#>                         Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
#> sd(d_Intercept)             0.49      0.04     0.42     0.57 1.00     3678
#> sd(criterion_Intercept)     0.48      0.04     0.41     0.55 1.00     3483
#>                         Tail_ESS
#> sd(d_Intercept)             3850
#> sd(criterion_Intercept)     3579
#> 
#> Regression Coefficients:
#>                     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> d_Intercept             0.67      0.05     0.58     0.78 1.00     2770     3604
#> criterion_Intercept     0.65      0.05     0.56     0.74 1.00     1856     2826
#> spacing_Intercept      -0.26      0.01    -0.27    -0.24 1.00     3468     3246
#> Ro_Intercept           -1.00      0.02    -1.05    -0.96 1.00     3693     3974
#> Rn_Intercept           -6.43      0.38    -7.23    -5.74 1.00     3895     4017
#> 
#> Constant Parameters:
#>                       Value
#> sdratio_Intercept      0.00
#> 
#> Note: d is the familiarity sensitivity; the observed ROC also carries recollection (Ro, Rn): see auc_sdt().
#> 
#> Draws were sampled using sample(hmc). For each parameter, Bulk_ESS
#> and Tail_ESS are effective sample size measures, and Rhat is the potential
#> scale reduction factor on split chains (at convergence, Rhat = 1).

The recollection terms are reported on the logit scale. latent_sdt() converts them to probabilities and prints them alongside the familiarity distributions:

latent_dp <- latent_sdt(fit_dp)
attr(latent_dp, "extra")
#>    parameter       mean        lower       upper
#> Ro        Ro 0.26886510 0.2599197734 0.277609508
#> Rn        Rn 0.00172835 0.0007269151 0.003208967

Recollection of old items (Ro) is credibly positive — it contributes to high-confidence “old” responses over and above familiarity, the dual-process signature. Recall-to-reject (Rn), by contrast, is estimated at essentially zero. That is exactly what we should expect for standard old/new recognition: recollecting that an item was not studied has little to work with here. Freeing Rn does no harm: the two-sided fit simply recovers the classic one-sided model. Recall-to-reject is expected to carry weight in single-probe and change-detection tests of visual working memory, where memory for the studied item also rejects the changed probe, whereas item-recognition tests favour recall-to-accept (Yonelinas 2024).

Two cautions. Freeing sdratio alongside Ro is weakly identified from a single ROC: in simulation the two are correlated at about −0.8 in the posterior and Ro is pulled down while exp(sdratio) is pulled above 1; keep the familiarity process equal-variance unless the design separates them. And a recollection probability near zero is reported as the tail of its prior: on the probability scale the interval cannot include 0, so the test of “no recollection” is a comparison with the fit that leaves the parameter fixed off, not the interval.

2.3 Two accounts of the same asymmetry

The core article fit these same data with an unequal-variance Gaussian (sdratio ~ 1, no recollection). Both models reproduce the asymmetric recognition ROC, but they tell different stories: unequal variance says the old-item strength distribution is wider, while dual-process says a separate recollection process adds high-confidence hits. We fit the unequal-variance model here too, for a direct comparison. When comparing the two, keep in mind that d is the familiarity \(d'\) in the equal-variance dual-process fit but \(d_a\), the separation in root-mean-square SD units, in the unequal-variance fit (see “Which sensitivity index?” in the core article):

model_uv <- sdt_rating(response = paste0("r", 1:6), stimulus = "stimulus")

fit_uv <- bmm(
  formula = bmf(d ~ 1 + (1 | id), criterion ~ 1 + (1 | id),
                spacing ~ 1, sdratio ~ 1),
  data = rating_data,
  model = model_uv,
  backend = "cmdstanr",
  cores = 4,
  chains = 4,
  iter = 4000,
  warmup = 1000,
  thin = 3,
  refresh = 0,
  silent = 2,
  file = "fits/bmmfit_sdt_dp_uv_vignette"
)

On probability axes both ROCs bend through the operating points. The z-transformed ROC (scale = "z") is the diagnostic that separates them: the unequal-variance Gaussian is a straight line, whereas the dual-process curve is bowed by the recollection mass.

plot(roc_sdt(fit_uv), observed = roc_observed(fit_uv), scale = "z") +
  ggplot2::ggtitle("Unequal-variance Gaussian")
plot(roc_sdt(fit_dp), observed = roc_observed(fit_dp), scale = "z") +
  ggplot2::ggtitle("Dual-process (recollection)")
The same recognition asymmetry, two accounts, on z-transformed ROC axes. Left: unequal-variance Gaussian — a straight zROC with slope below one. Right: dual-process — recollection bows the zROC. Points are the observed operating points.The same recognition asymmetry, two accounts, on z-transformed ROC axes. Left: unequal-variance Gaussian — a straight zROC with slope below one. Right: dual-process — recollection bows the zROC. Points are the observed operating points.

Figure 2.2: The same recognition asymmetry, two accounts, on z-transformed ROC axes. Left: unequal-variance Gaussian — a straight zROC with slope below one. Right: dual-process — recollection bows the zROC. Points are the observed operating points.

In practice the two are hard to separate from a single ROC: recognition zROCs are only gently curved, and an unequal-variance Gaussian mimics the dual-process shape closely (the same flexibility caveat that applies to the extreme-value vs Gaussian comparison in the core article; Meyer-Grant et al. (2026)). The choice is best driven by theory and by whether parameters stay invariant across conditions — for instance whether a manipulation moves recollection but leaves familiarity in place, or the reverse, as Yonelinas (2024) reports for working-memory ROCs — rather than by ROC fit alone. The continuous dual-process model (Wixted and Mickes 2010) and finite-mixture SDT (DeCarlo 2002) are further variations on the same theme of a second component shaping the ROC.

2.4 Posterior predictive checks

As for the standard rating model, pp_check() compares the observed rating-category proportions against the posterior predictive distribution, faceted by stimulus:

pp_check(fit_dp, ndraws = 100)

If recollection is doing real work, the dual-process model should track the high-confidence categories (r1 and r6) more closely than an equal-variance familiarity-only model, whose single strength axis cannot put enough mass at the extremes.

3 Meta-d′

3.1 The model

A confidence-rating task answers two different questions at once. Type-1: how well does the observer tell old from new? That is ordinary sensitivity, d. Type-2: how well does the observer’s confidence track whether each decision was actually correct? That is metacognitive sensitivity, and it need not match type-1 sensitivity — an observer can discriminate well yet place confidence poorly, or vice versa (Maniscalco and Lau 2012).

Meta-d′ (Maniscalco and Lau 2012) expresses type-2 sensitivity in the same units as type-1 d. It is the sensitivity that a metacognitively ideal signal-detection observer would need in order to produce the observed confidence data, holding the type-1 decision fixed — that is, the old/new response rates are constrained to match what d already implies, so meta-d′ is identified purely from the spread of confidence within each response. The natural summary is the

\[ \text{M-ratio} = \frac{\text{meta-}d'}{\texttt{d}}, \]

the metacognitive efficiency: a value of 1 means confidence is as informative as the decision (ideal), below 1 means confidence carries less information than the decision used (the common case), and above 1 means confidence draws on information the decision did not.

Rather than estimating meta-d′ directly, bmm estimates the log M-ratio, logmratio \(= \log(\text{meta-}d'/d')\), and recovers meta-d′ as exp(logmratio) * d. This is the parameterization used by the HMeta-d toolbox (Fleming 2017): the M-ratio is the quantity researchers actually report, so making it the estimated parameter places the prior, hierarchical between-subject SD, and any group contrasts directly on metacognitive efficiency. It also keeps meta-d′ positive and regularizes it toward d, and it anchors the ideal point — perfect metacognition, meta-d′ = d — at logmratio = 0, which recovers the standard rating model. Add logmratio to the formula to estimate it; extract the M-ratio posterior with mratio().

Metacognitive efficiency. Both panels have the same type-1 sensitivity (old/new discrimination) and the same old/new criterion (solid line). When metacognition is efficient (left, M-ratio = 1) the confidence thresholds (dashed) are well spread, so confidence separates likely-correct from likely-incorrect responses. When it is inefficient (right, M-ratio < 1) the thresholds bunch toward the criterion: confidence varies little and is weakly diagnostic of accuracy.

Figure 3.1: Metacognitive efficiency. Both panels have the same type-1 sensitivity (old/new discrimination) and the same old/new criterion (solid line). When metacognition is efficient (left, M-ratio = 1) the confidence thresholds (dashed) are well spread, so confidence separates likely-correct from likely-incorrect responses. When it is inefficient (right, M-ratio < 1) the thresholds bunch toward the criterion: confidence varies little and is weakly diagnostic of accuracy.

3.2 Worked example: metacognitive efficiency in recognition memory

We stay with the same Pratte et al. (2010) recognition data reshaped above (rating_data). No new response format is needed: in a confidence-rating task the 6-point scale is exactly the joint type-1/type-2 response — the side of the scale is the old/new decision and the distance from the middle is confidence — so the same counts that identified d also identify metacognitive efficiency. Only the version changes:

model_md <- sdt_rating(response = paste0("r", 1:6), stimulus = "stimulus",
                       version = "metad")

fit_md <- bmm(
  formula = bmf(d ~ 1 + (1 | id), criterion ~ 1 + (1 | id),
                spacing ~ 1, logmratio ~ 1 + (1 | id)),
  data = rating_data,
  model = model_md,
  backend = "cmdstanr",
  cores = 4,
  chains = 4,
  iter = 7000,
  warmup = 1000,
  thin = 6,
  refresh = 0,
  silent = 2,
  file = "fits/bmmfit_sdt_metad_pratte_vignette"
)
summary(fit_md)
#>   Model: sdt_rating(response = paste0("r", 1:6),
#>                     stimulus = "stimulus",
#>                     version = "metad") 
#>   Links: d = identity; criterion = identity; spacing = identity; sdratio = identity; logmratio = identity 
#> Formula: d ~ 1 + (1 | id)
#>          criterion ~ 1 + (1 | id)
#>          spacing ~ 1
#>          sdratio = 0
#>          logmratio ~ 1 + (1 | id) 
#>    Data: rating_data (Number of observations: 194)
#>   Draws: 4 chains, each with iter = 7000; warmup = 1000; thin = 6;
#>          total post-warmup draws = 4000
#> 
#> Multilevel Hyperparameters:
#> ~id (Number of levels: 97) 
#>                         Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
#> sd(d_Intercept)             0.40      0.03     0.34     0.46 1.00     3768
#> sd(criterion_Intercept)     0.36      0.03     0.31     0.42 1.00     3866
#> sd(logmratio_Intercept)     0.64      0.06     0.53     0.78 1.00     3833
#>                         Tail_ESS
#> sd(d_Intercept)             3896
#> sd(criterion_Intercept)     3690
#> sd(logmratio_Intercept)     4039
#> 
#> Regression Coefficients:
#>                     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> d_Intercept             1.10      0.04     1.02     1.19 1.00     3654     3892
#> criterion_Intercept     0.57      0.04     0.50     0.64 1.00     3014     3556
#> spacing_Intercept      -0.44      0.00    -0.45    -0.43 1.00     3941     3836
#> logmratio_Intercept    -0.20      0.07    -0.35    -0.06 1.00     3540     4008
#> 
#> Constant Parameters:
#>                       Value
#> sdratio_Intercept      0.00
#> 
#> Draws were sampled using sample(hmc). For each parameter, Bulk_ESS
#> and Tail_ESS are effective sample size measures, and Rhat is the potential
#> scale reduction factor on split chains (at convergence, Rhat = 1).

The M-ratio is the headline quantity, so bmm provides it directly: mratio() reconstructs meta-d′ \(= \exp(\texttt{logmratio}) \times \texttt{d}\) from the fit and returns a posterior summary of both the M-ratio and meta-d′ (with the full per-draw posteriors kept in the draws attribute for plotting or contrasts).

mratio(fit_md)
#> Metacognitive efficiency (meta-d' SDT)
#> posterior mean/median with 95% CrI [lower, upper]
#>  parameter  mean median lower upper
#>     mratio 0.819  0.818 0.705 0.939
#>      metad 0.904  0.902 0.767 1.050

The population M-ratio sits a little below 1, the typical finding for recognition memory: confidence tracks accuracy well but not perfectly, carrying slightly less information than the old/new decision itself. The (1 | id) term on logmratio lets metacognitive efficiency vary across subjects, so this single fit also gives a posterior for individual differences in metacognition — the question that motivates most meta-d′ analyses.

The ROC makes the inefficiency visible. For a metad fit the smooth curve drawn by roc_sdt() is the type-1 (d, sdratio) ROC, and the threshold points are the model’s confidence operating points; they lie inside the curve when the M-ratio is below 1, by the amount of the metacognitive inefficiency. Only the middle threshold, the old/new criterion, sits on the curve, because the type-1 rates are held to d.

plot(roc_sdt(fit_md), observed = roc_observed(fit_md))
Meta-d′ fit: the smooth curve is the type-1 ROC implied by d; the confidence operating points (t1 to t5) fall inside it, except the criterion t3, by the metacognitive inefficiency.

Figure 3.2: Meta-d′ fit: the smooth curve is the type-1 ROC implied by d; the confidence operating points (t1 to t5) fall inside it, except the criterion t3, by the metacognitive inefficiency.

Recognition ROCs are classically asymmetric, which is usually modelled as unequal variance; adding sdratio ~ 1 to the formula fits an unequal-variance meta-d′ model. In bmm the two parameters draw on different parts of the data: sdratio is identified from the slope of the zROC across the whole rating scale, logmratio from how confidence spreads within each response. The meta-d′ literature, which fits type-2 ROCs on their own, warns that there the variance ratio and metacognitive efficiency are confounded and recommends the equal-variance model unless the variance ratio is known independently (Maniscalco and Lau 2014; Fleming 2017); estimates from an unequal-variance bmm fit are therefore not comparable with an MLE meta-d′ computed under a fixed \(s\). d and meta-d′ are then both \(d_a\) indices, so the M-ratio keeps its meaning.

3.3 Interpreting meta-d′

Meta-d′ is most useful when the substantive question is about metacognition — whether confidence is well-calibrated to performance — rather than about discrimination itself. Expressing type-2 sensitivity on the d scale makes the M-ratio comparable across tasks and observers with different type-1 performance, which is why it has become the standard index of metacognitive efficiency (Maniscalco and Lau 2012; Fleming 2017).

Two cautions carry over from the rest of SDT. First, like all the rating models here, meta-d′ is fit to aggregated counts, so the type-2 estimate is only as informative as the number of trials per confidence category. Second, meta-d′ inherits the standard model’s assumptions about how confidence criteria are placed; systematic pp_check() deviations flag when those assumptions strain.

3.3.1 Confidence-threshold parameterization

In the canonical meta-d′ model the type-2 confidence criteria are free: their spacing is exactly what makes the metacognitive fit informative. In bmm those criteria are the rating thresholds, so the threshold_type you choose (core SDT article) governs how freely they can move. The delta-based parameterizations ("log_distance", "log_ratio") leave each threshold distance free and stay closest to the textbook meta-d′ estimator. The two-parameter "parsimonious" (default) and "equidistant" types instead tie the thresholds to a single spacing parameter: this regularizes the fit and is often desirable with few trials per category, but it constrains the type-2 ROC and can mask genuine asymmetries in how confidence is used for “old” versus “new” responses. If the metacognitive question hinges on that asymmetry, prefer a delta-based threshold_type. Whatever the parameterization, sdt_thresholds() reconstructs the fitted confidence criteria on the latent scale — it works for all three versions, so the type-2 criterion placements can be inspected directly.

3.3.2 How the type-1 criterion anchors confidence

Meta-d′ models must fix the type-2 confidence scale relative to the type-1 criterion. bmm uses the absolute convention — the confidence criteria are anchored at the same boundary as the old/new decision (meta-\(c = c\), with \(c\) measured from the midpoint between the means), as in the HMeta-d toolbox (Fleming 2017). This holds whether the formula estimates the type-1 boundary as criterion or as bias. The maximum-likelihood estimator instead uses a relative convention that scales the anchor with metacognitive efficiency (meta-\(c' = c'\), i.e. meta-\(c = M \cdot c\)) (Maniscalco and Lau 2014); Fleming (2017) states that relative constraint for the maximum-likelihood estimator and writes the hierarchical model’s type-2 probabilities with the type-1 criterion itself (its Appendix). bmm does not currently expose that toggle. The two rarely diverge materially when the criterion sits near the centre of the rating scale, but with a strongly biased criterion the choice can shift meta-d′, so it is worth keeping in mind when comparing estimates against toolboxes that use the relative anchor.

3.4 Posterior predictive checks

The rating-profile check works as for the other rating models, faceted by stimulus. For meta-d′ the categories to watch are the interior ones: the model constrains the total “old”/“new” rates to match d, so any misfit shows up in how confidence spreads within each response side. Systematic one-sided deviations there suggest the confidence thresholds are too constrained — see the threshold-parameterization note above.

pp_check(fit_md, ndraws = 100)

4 Continuous dual-process SDT

The dual-process model above treats recollection as a threshold process: an old item is either recollected — landing in the most-confident category — or it is not. The continuous dual-process (CDP) model (Wixted and Mickes 2010) keeps the dual-process intuition but makes recollection continuous. Every item carries a familiarity signal \(F\) and a recollection signal \(R\), and the old/new confidence rating is driven by their sum, the aggregate memory strength \(S = F + R\). What makes it a dual-process model is that the Remember/Know judgment is read off \(R\) directly: an “old” response is called Remember when recollection clears a criterion \(r\) on the \(R\) axis, and Know otherwise.

This needs a richer response than the rating versions above — not just a confidence rating, but a Remember/Know judgment on every “old” response — so bmm provides it as a dedicated model, sdt_cdp(), rather than a version of sdt_rating(). For a target, \(F \sim \mathrm{Normal}(\mu_F, 1)\) and \(R \sim \mathrm{Normal}(\mu_R, \sigma_R)\) (lures fix both means to 0 and \(\sigma_R\) to 1); dfam and drec are the two sensitivities and sigmar is \(\log \sigma_R\). Old/new confidence partitions the strength axis \(S\) with ordered thresholds, exactly as in the rating model, while the Remember/Know split is the probability that \(R\) exceeds rcrit within each confidence bin — a region of the two-dimensional \((F, R)\) plane. For the Remember/Know split bmm computes it exactly with the bivariate-normal CDF; the Know/Guess split of the three-way model adds a numerical integral over the strength bin (20-node Gauss-Legendre, accurate to about \(10^{-5}\) in the probability).

4.1 Worked example: Remember/Know in recognition memory

We fit the model to the group Remember/Know ROC data of Rotello et al. (2005) (neutral condition): a 6-point scale where rating 1 is a confident “new” response and ratings 2–6 are “old” responses, each accompanied by a Remember or Know judgment. We enter the data in tidy long form — one row per combination of stimulus class, judgment, and confidence level, with a count column — since that is how Remember/Know data typically leave an experiment (trial-level data work the same way, just without count):

rotello_long <- rbind(
  data.frame(stimulus = 1L, judgment = "new",      confidence = 1L,  count = 290),
  data.frame(stimulus = 1L, judgment = "know",     confidence = 2:6, count = c(122, 106, 101, 92, 59)),
  data.frame(stimulus = 1L, judgment = "remember", confidence = 2:6, count = c(26, 38, 61, 109, 433)),
  data.frame(stimulus = 0L, judgment = "new",      confidence = 1L,  count = 745),
  data.frame(stimulus = 0L, judgment = "know",     confidence = 2:6, count = c(199, 124, 84, 45, 13)),
  data.frame(stimulus = 0L, judgment = "remember", confidence = 2:6, count = c(46, 29, 47, 51, 55))
)
head(rotello_long)
#>   stimulus judgment confidence count
#> 1        1      new          1   290
#> 2        1     know          2   122
#> 3        1     know          3   106
#> 4        1     know          4   101
#> 5        1     know          5    92
#> 6        1     know          6    59

Like sdt_rating(), the model itself is fit to aggregated counts — one row per cell and one count column per response category. aggregate_sdt_cdp_data() pivots the long rows into these canonical columns; every column other than judgment, confidence, and count (here just stimulus) defines the cells and is carried over:

rotello <- aggregate_sdt_cdp_data(rotello_long, judgment = "judgment",
                                  confidence = "confidence", count = "count")
rotello
#>   stimulus new1 know2 know3 know4 know5 know6 remember2 remember3 remember4
#> 1        1  290   122   106   101    92    59        26        38        61
#> 2        0  745   199   124    84    45    13        46        29        47
#>   remember5 remember6
#> 1       109       433
#> 2        51        55

The 22 long rows collapse to one row per stimulus class, with columns new1 (the single “new” level) and know2…know6 / remember2…remember6 on the unified confidence scale. This is also the format rsdt_cdp() simulates directly, and if your own wide columns carry a shared prefix (say cdp_new1), you declare it once via the constructor’s response argument. The scale is asymmetric — one “new” level and five “old” levels — which the constructor is told via n_new and n_old (the two need not match). We free sigmar so recollection can add variance to the old-item strength distribution (the canonical Wixted–Mickes result) and keep the familiarity–recollection correlation rho at its default of zero, the classic independent-process model:

model_cdp <- sdt_cdp(stimulus = "stimulus", n_new = 1, n_old = 5)

fit_cdp <- bmm(
  formula = bmf(dfam ~ 1, drec ~ 1, criterion ~ 1, spacing ~ 1,
                rcrit ~ 1, sigmar ~ 1),
  data = rotello, model = model_cdp,
  backend = "cmdstanr", cores = 4, chains = 4, iter = 2000,
  refresh = 0, silent = 2,
  file = "assets/bmmfit_sdt_cdp_vignette"
)
summary(fit_cdp)
#>   Model: sdt_cdp(stimulus = "stimulus",
#>                  n_new = 1,
#>                  n_old = 5) 
#>   Links: dfam = identity; drec = identity; criterion = identity; spacing = identity; rcrit = identity; sigmar = identity; rho = identity; kcrit = identity 
#> Formula: dfam ~ 1
#>          drec ~ 1
#>          criterion ~ 1
#>          spacing ~ 1
#>          rcrit ~ 1
#>          sigmar ~ 1
#>          rho = 0
#>          kcrit = -100 
#>    Data: (Number of observations: 2)
#>   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
#>          total post-warmup draws = 4000
#> 
#> Regression Coefficients:
#>                     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
#> dfam_Intercept          0.77      0.06     0.65     0.90 1.00     2613     2490
#> drec_Intercept          0.81      0.07     0.68     0.94 1.00     2704     2859
#> criterion_Intercept     0.07      0.05    -0.02     0.16 1.00     3025     2575
#> spacing_Intercept      -0.37      0.03    -0.42    -0.32 1.00     2595     2587
#> rcrit_Intercept         0.92      0.04     0.84     1.01 1.00     2696     2695
#> sigmar_Intercept        0.39      0.05     0.28     0.48 1.00     2834     2861
#> 
#> Constant Parameters:
#>                       Value
#> rho_Intercept          0.00
#> kcrit_Intercept     -100.00
#> 
#> Draws were sampled using sample(hmc). For each parameter, Bulk_ESS
#> and Tail_ESS are effective sample size measures, and Rhat is the potential
#> scale reduction factor on split chains (at convergence, Rhat = 1).

Recollection (drec ≈ 0.81) and familiarity (dfam ≈ 0.77) contribute comparable sensitivities, the Remember criterion sits well into the recollection distribution (rcrit ≈ 0.92), and exp(sigmar) ≈ 1.47 puts the recollection SD above one — the model’s account of the recognition-ROC asymmetry as added recollection variance rather than a uniformly wider strength distribution. Despite using the two-parameter parsimonious thresholds rather than five free criteria, these estimates reproduce the maximum-likelihood values Wixted and Mickes (2010) report for exactly these data (their Table 3: \(\mu_F = 0.78\), \(\mu_R = 0.81\), \(\sigma_R = 1.48\), \(r = 0.92\)).

Two further options extend the model, each opt-in. The familiarity–recollection correlation is freed with rho ~ 1 (and can itself be predicted, e.g. rho ~ condition); it is bounded to \((-1, 1)\) internally and is a within-item correlation, distinct from a between-subject correlation of random effects (which you would write as (1 |p| id)). And when the task also collects an explicit Guess response, include "guess" judgments in the long data: aggregate_sdt_cdp_data() turns them into guess count columns, whose presence switches on the three-way Remember/Know/Guess model with a familiarity criterion kcrit separating Know from Guess (free it with kcrit ~ 1). That model has a hard boundary — a Guess response in a confidence bin is possible only while rcrit + kcrit exceeds the bin’s lower threshold — and hierarchical fits can report divergent transitions near it; ?sdt_cdp describes the boundary and what to try.

5 Choosing and comparing the models

The first three models share the same confidence-rating response interface and the same familiarity core, so the choice is about which additional question the data are meant to answer:

  • Reach for version = "dpsdt" when the question is about recollection — whether a threshold retrieval process contributes beyond graded familiarity, as in recognition-memory and change-detection paradigms.
  • Reach for version = "metad" when the question is about metacognition — whether confidence is efficiently calibrated to accuracy.
  • Stay with version = "standard" when a single strength process suffices; both extensions reduce to it when their extra parameter is switched off (Ro, Rn → 0; logmratio = 0, i.e. meta-d′ = d).
  • Reach for sdt_cdp() when the data carry explicit Remember/Know judgments: it models that richer response directly — recollection as a continuous second axis — rather than collapsing it to a confidence rating.

Because each extension nests the standard model, the most direct evidence is the posterior of the extra parameter: is Ro credibly greater than zero, is logmratio credibly different from zero (M-ratio different from 1)? That, together with pp_check() and the ROC/zROC fit, is the practical guide. A formal predictive comparison via loo() is not appropriate for these aggregated-count models — leaving out one multinomial observation removes a large, influential block of data and the PSIS-LOO approximation becomes unreliable. The principled alternative is k-fold cross-validation with brms::kfold(), which refits on held-out folds. As always, let theory and parameter invariance across designs — not ROC fit alone — arbitrate between accounts that can mimic one another (Meyer-Grant et al. 2026; Robinson et al. 2023).

References

DeCarlo, Lawrence T. 2002. “Signal Detection Theory with Finite Mixture Distributions: Theoretical Developments with Applications to Recognition Memory.” Psychological Review 109 (4): 710–21. https://doi.org/10.1037/0033-295X.109.4.710.
Fleming, Stephen M. 2017. “HMeta-d: Hierarchical Bayesian Estimation of Metacognitive Efficiency from Confidence Ratings.” Neuroscience of Consciousness 2017 (1): nix007. https://doi.org/10.1093/nc/nix007.
Maniscalco, Brian, and Hakwan Lau. 2012. “A Signal Detection Theoretic Approach for Estimating Metacognitive Sensitivity from Confidence Ratings.” Consciousness and Cognition 21 (1): 422–30. https://doi.org/10.1016/j.concog.2011.09.021.
Maniscalco, Brian, and Hakwan Lau. 2014. “Signal Detection Theory Analysis of Type 1 and Type 2 Data: Meta-d’, Response-Specific Meta-d’, and the Unequal Variance SDT Model.” In The Cognitive Neuroscience of Metacognition, edited by Stephen M. Fleming and Christopher D. Frith. Springer. https://doi.org/10.1007/978-3-642-45190-4_3.
Meyer-Grant, Constantin G., David Kellen, Samuel M. Harding, and Henrik Singmann. 2026. “Extreme-Value Signal Detection Theory for Recognition Memory: The Parametric Road Not Taken.” Psychological Review, ahead of print. https://doi.org/10.1037/rev0000615.
Pratte, Michael S., Jeffrey N. Rouder, and Richard D. Morey. 2010. “Separating Mnemonic Process from Participant and Item Effects in the Assessment of ROC Asymmetries.” Journal of Experimental Psychology: Learning, Memory, and Cognition 36 (1): 224–32. https://doi.org/10.1037/a0017682.
Robinson, Maria M., Isabella C. DeStefano, Edward Vul, and Timothy F. Brady. 2023. “How Do People Build up Visual Memory Representations from Sensory Evidence? Revisiting Two Classic Models of Choice.” Journal of Mathematical Psychology 117: 102805. https://doi.org/10.1016/j.jmp.2023.102805.
Rotello, Caren M., Neil A. Macmillan, Jeffrey A. Reeder, and Michael Wong. 2005. “The Remember Response: Subject to Bias, Graded, and Not a Process-Pure Indicator of Recollection.” Psychonomic Bulletin & Review 12 (5): 865–73. https://doi.org/10.3758/BF03196778.
Wixted, John T., and Laura Mickes. 2010. “A Continuous Dual-Process Model of Remember/Know Judgments.” Psychological Review 117 (4): 1025–54. https://doi.org/10.1037/a0020874.
Yonelinas, Andrew P. 1994. “Receiver-Operating Characteristics in Recognition Memory: Evidence for a Dual-Process Model.” Journal of Experimental Psychology: Learning, Memory, and Cognition 20 (6): 1341–54. https://doi.org/10.1037/0278-7393.20.6.1341.
Yonelinas, Andrew P. 2024. “The Role of Recollection and Familiarity in Visual Working Memory: A Mixture of Threshold and Signal Detection Processes.” Psychological Review 131 (2): 321–48. https://doi.org/10.1037/rev0000432.