What won and what lost, in full
- Positive results, one per sentence. Next-category transfer: the delta clears zero at 10
million rows and holds at the full corpus on both seeds, after being indistinguishable from zero at 3
million. Fraud: embeddings lift
fraud PR-AUC at both of the corpus sizes where that baseline still has headroom, and at the stronger of
the two, 10 million rows, it moves from
0.638 to
0.904. Corridors: averaging
the model with the seasonal naive at weights fixed before the run lowers macro MASE from
0.53 to
0.506, a point comparison with no interval
claimed. Offers: on the randomized Criteo holdout, uplift targeting
concentrates 5.9 times
the average site-visit effect into the top decile and beats response ranking there, paired CI
[0.008545, 0.014453].
Protection: the score, added to the counting control instead of set against it, moves PR-AUC from
0.1282
to 0.3296
(difference
0.2014,
interval [0.1480, 0.2450])
and ROC-AUC by
0.0129
([0.0041, 0.0226]),
both clear of zero; the protection exhibit below carries the full table. One caveat applies to that
row: the combination was chosen after the two single scores had been
compared, so it is a reported finding and not a pre-registered one. It is unweighted, standardized,
label-free and has nothing fitted, which is why we still trust it, but the corridor combination above
was pre-registered before its run and this one was not, and that difference is reported explicitly rather
than left implicit.
- Null and negative results, reported in full: the label-free surprise score read off the same
frozen backbone loses to a counts-only rarity control on ROC-AUC and only ties it on PR-AUC, so the
model does not carry that task on its own. The full-corpus fraud delta is a null on a saturated
baseline, and the fraud AUC delta spans zero at every corpus size, which is why PR-AUC leads on that
task. The merchant-axis run, our two-sided leg, comes back a null on both tasks, and pair retention,
the merchant-native task we built to ask the question properly, is a null too, so whether two-sided modelling outperforms
single-sided modelling remains an open question rather than a result. The corridor model loses pooled to a
seasonal naive and wins five of twelve corridors. Uplift targeting loses to plain response ranking on
the rare conversion outcome of the randomized Criteo benchmark in Section 6, at every targeting depth
we measured.
- The measured effect of the evaluation protocol: we re-ran the same frozen backbone under four
evaluation protocols, tightening the guards one step at a time, with the one step that moves more than
one thing named as such in Section 5. A permissive protocol reports
0.0590 on next-category top-1. Making
the split entity-disjoint sends the same number to
-0.0240, below zero. The gain that
survives every guard is the one we ship,
0.0218. The ladder is further down this
section.
- Why both sets of results are reported: each comparison above was pre-registered before results
existed, and the product is the measurement layer. Knowing which is which, with confidence intervals,
is the deliverable.
The public blueprint and the differences in our approach
We are not first on this corpus and we do not claim to be. In June 2026 NVIDIA published a transaction
foundation model blueprint50 that pretrains a decoder-only Llama-style model of
about 29M parameters with a next-token objective on the same public IBM TabFormer
data, then feeds its embeddings to an XGBoost fraud classifier and reports an average-precision lift over
that baseline. The code is public under Apache-2.052. Ours differs in two ways. The
model is an encoder trained with a masked-field objective rather than a decoder trained to predict the next
token, and the architecture is not what we are offering: our contribution is the evaluation protocol
wrapped around the backbone, which is why the table below carries pre-registered tasks, a named leakage
design, entity-level confidence intervals, and the results that came back null. We do not put their fraud
numbers beside ours anywhere on this page, because the architecture, the downstream task setup and the test
split all differ, so the two are not comparable.
Two pre-registered tasks and what they buy
The central question is whether the backbone's embeddings carry signal that strong per-task features do not
already have. We tested it the hard way. The baseline is LightGBM on per-entity temporal aggregates, named
exactly: per-account transaction count, amount mean, spread, maximum and last value, recency and tenure,
and the previous merchant category and city with their frequency encodings. That is the pattern that wins
on Amex-style data in public competition53. It does not yet include a per-user
category histogram; that harder baseline is pre-registered for Round 2 in Section 8. The comparison adds
backbone embeddings to that same baseline.
Both tasks were pre-registered:
- Fraud detection (this is the Protection head, v0): baseline AUC
0.99994, with embeddings
0.99961, delta CI
[-0.001213, 0.000093]. PR-AUC reported alongside:
0.99389 baseline,
0.996 with embeddings. This full-corpus run is
saturated and the delta is an honest null; the scaling check below shows the same task at the two
smaller corpus sizes, where the baseline still has headroom.
- Next merchant category (the growth analogue): baseline top-1 accuracy
0.235, with embeddings
0.257, delta CI
[0.0103, 0.0343].
Confidence intervals are entity-level paired bootstrap. Deltas are reported exactly as obtained.
What it buys. One embedding service standing behind several models instead of a
separate feature pipeline per task, which is where the operating saving is located. It only counts
where the transfer is real, and that is why the nulls are printed beside the gains rather than left out
of the table.
The four guards and the sampling rule
Pretraining corpus cut at 2017-08-25T09:37:00Z, before the
evaluation window. Label columns excluded from the pretraining vocabulary. Embeddings are as-of: nothing at
or after the scored transaction feeds them. Account identifiers hashed, so unseen entities embed
inductively. These four checks are asserted in the results file rather than only stated here. The same file
records the split and the sampling rule: entity-disjoint by account,
400 of
2,000 accounts held out, rows drawn
"uniform + all fraud positives kept". Keeping every positive and thinning the negatives
to reach the row cap raises the positive rate in the scored set above the rate in the window it comes
from, so the PR-AUC levels on this page read as a comparison between the two arms rather than as a rate a
live queue would see.
Four evaluation rungs, with each guard priced separately
Published transaction foundation model demonstrations report downstream lifts much larger than the one
in the table above. The question is whether that gap is attributable to the model or to the measurement, and it
can be answered rather than argued. We took the same frozen backbone, changed nothing about it, and ran the
same two downstream tasks under four evaluation protocols, turning the guards on one step at a time. L0 is
the permissive shape: a temporal-only split, so the same accounts sit on both sides; a baseline without
per-entity temporal aggregates; and one pooled embedding per account computed over that account's whole
sequence, so it can see the scored transaction and everything after it. L1 turns on the entity-disjoint
split by account. L2 adds as-of embeddings that stop strictly before the scored transaction. L3 adds the
per-entity aggregates to the baseline, which is the protocol every other number on this page already
uses, so L3 has to reproduce the table above and the results file records by how much it does.
Two further properties of this ladder should be stated before the numbers. The first is that only the
evaluation protocol moves. The pretrain-side guards, the label columns kept out of the vocabulary and the
account identifiers kept out of it as well, stay on at every rung, so nothing here is a claim about the
pretraining. The second is that the ladder is conservative: the merchant-side embedding stays pre-cut
pooled at all four rungs, so only the account-side embedding varies, and L0 is a lower bound on what a
fully permissive protocol would show, not an upper bound. The rung definitions, the metric and the
bootstrap scheme were written into the decision log and committed before the first run.
What it buys. The ladder provides a commercial answer as well as a methodological one. When a partner
pays on certified lift, the first question anyone asks is which protocol produced the number. Section 8
puts the fee basis on a table in Section 6 that the partner can recompute from their own arm counts, and
the ladder is what makes the protocol behind it checkable instead of assertable. It is also worth more
than this project: what was built is a rig that takes any frozen checkpoint and prices its transfer
claim under four protocols, and it is independent of the source of the checkpoint. That makes it a triage tool for
any model claim the CoE is asked to believe, from a vendor or from an internal team, and a common
protocol to settle it when two teams disagree. The rig remains useful whether or not One Loop ships.
Reading the top panel left to right: the next-category delta starts at 0.0590 under the permissive protocol and ends at 0.0218 under the protocol this page ships. The single guard that moves it the most is the entity-disjoint split, which takes it from 0.0590 to -0.0240. That step also changes which rows are scored, so its change is a difference of point estimates and carries no interval.
L0's temporal split puts 1,530 accounts on both sides of the split, which is the guard being removed, asserted in code rather than assumed; L3 reproduces the eight shipped point metrics to a largest absolute difference of 0; the pretrain-side guards stay on at every rung; only the evaluation protocol moves.
The result is not a discount on our number; it is that the permissive protocol and the shipped
protocol are not measuring the same thing. Under L0 the next-category delta is
0.0590 on top-1 and
0.1064 on top-5, the largest figures
anywhere in this ladder. When the split is switched to entity-disjoint, that lift does not settle toward the
shipped value; it disappears: top-1 lands at
-0.0240, with an interval of
[-0.0373, -0.0112] that stays below zero, and
top-5 lands on a null at [-0.0158, 0.0140]. Our
reading of that reversal is that most of the L0 lift was account identity rather than transfer: with
the same accounts on both sides, one pooled vector per account works as a key to that account's own
category mix, and it stops working the moment the accounts are ones the model has not seen. The
with-embeddings arm at L1 stops almost immediately under its own entity-disjoint validation fold, which
is the model detecting the same thing. That step also changes which rows are scored, so we report no
interval on the change itself and let the L1 interval carry the point.
The transfer signal appears once the embedding is made as-of. At L2 top-1 is
0.0159 and top-5 is
0.0547, and because L1 and L2 are scored
on identical rows that guard can be priced directly: it moves top-1 by
0.0399, interval
[0.0249, 0.0561], and top-5 by
0.0547, interval
[0.0385, 0.0742], both clear of zero. The
last guard is the one that reduces our lift, and the two metrics disagree about the size of the reduction. Equipping the
baseline with per-entity aggregates moves top-1 by
0.0060 with an interval of
[-0.0020, 0.0152] that spans zero, so on
that metric L2 and L3 are not distinguishable from each other; on top-5 it takes lift away,
-0.0329, interval
[-0.0436, -0.0219], clear of zero. The
rung this page ships is therefore the strictest one rather than the most favourable one, and it still reports a gain
whose interval clears zero on both metrics.
On the fraud task the ladder cannot discriminate, and we say that rather than reading point estimates.
The baseline already scores 0.985 PR-AUC at
its weakest rung and 0.99389 at the shipped
one, and all eight per-rung fraud intervals, four on AUC and four on PR-AUC, span zero. That task is
saturated on this corpus before the protocol gets a chance to matter, which is the same reading the
transfer table above already gives. Two further details the exhibit does not hide. The L0 rung scores a
different set of rows, 1,943 test accounts
against 391 at the guarded rungs and
809 fraud positives against
945, so nothing in the L0 column is paired
with the rest. L3 also reproduces the transfer table above exactly, to a largest absolute difference of
0 across the eight point metrics, which is the
check that keeps this ladder attached to the rest of the page.
We also re-ran this ladder from scratch rather than trusting the first run. On the machine that produced
the file the comparison returns CHECK OK, exit 0 across
424 numeric leaves, at a largest difference
of 1.110e-16, which is double-precision rounding. Run on a
different CPU vendor the same comparison reproduces
398 of 424 leaves bit-identically and differs on
the rest at a largest absolute difference of
1.349e-05, all of it inside L0's next-category arm,
where a many-class model breaks argmax ties differently under a different floating-point reduction order.
Rendered numerals on this page that move as a result:
none, since every affected
quantity is printed here at four decimals and both values round to the same figure. We report that
because a reviewer who reruns this on their own hardware should know what to expect, and because a
reproducibility claim is more useful when its tolerance is stated alongside it.
A real corpus, three heads, two seeds
The ladder above changes the protocol and holds the corpus fixed. Corpus is a variable in the same way,
so the next question is what happens when the corpus changes and the protocol does not. We ran the
shipped L3 protocol again on real retail transactions from dunnhumby's Complete Journey, with
byte-identical training code, the same guards, the same entity-clustered paired bootstrap and the same
decision rule: two pretraining seeds, three heads, every split entity-disjoint and pre-registered
(household-disjoint for the transfer and offers evaluations, store-disjoint for the store head).
Everything was pre-registered at 6c9c7a9 with a pre-run amendment at
51c69e5, both committed before the run, and the rule that decides what counts was
fixed in the same place: "pre-registered in CJ-REPLICATION-PREREG.md: positive only if both seed intervals sit above zero; anything else ships as a null or mixed result; no third seed, no protocol changes after seeing numbers".
Under the L3 protocol on the real Complete Journey corpus the backbone's transfer gain on next-commodity top-1 is negative in both pretraining seeds (-0.0160 and -0.0147), with both 95% household-clustered intervals below zero. Per the pre-registration this ships as obtained. The with-embedding arm lands at
0.5041 and
0.5053 on top-1, both under the
0.5101 majority-class floor, so here the
embeddings do not only fail to add accuracy; they reduce it below the level the model would have reached by predicting the most
common class. Our reading is the ladder's second axis behaving as designed. The ladder showed the
protocol is a variable; this shows the corpus is one too, and on this corpus the answer moved.
On this corpus the backbone's store embeddings add measurable signal over the counts-only control for post-cut sales growth (macro-F1 delta +0.1912, 95% interval [0.0064, 0.3865] above zero). The second pretraining seed repeats it:
On this corpus the backbone's store embeddings add measurable signal over the counts-only control for post-cut sales growth (macro-F1 delta +0.2242, 95% interval [0.0449, 0.4343] above zero). The control is counts only, three pre-cut
features and nothing more, and the outcome is growth rather than volume by design:
raw post-cut volume is mostly pre-cut size restated; the counts control would win by construction without answering the embedding question. The universe is
231 eligible stores split into a
46-store test set, which is why the intervals are wide
and why they are printed wide. Accuracy was pre-registered alongside macro-F1 as a reported metric, with
the decision rule keyed to macro-F1, and it is the weaker of the two: the seed 7 accuracy delta is
+0.1957 with an interval of
[-0.0217, 0.4130] that spans zero, so on that endpoint that
seed is a null, while seed 8 clears it at
+0.2174
[0.0217, 0.4136]. This is predictive and not causal: nothing
here estimates what a backbone embedding causes. The offers head came back mixed and is reported as mixed, null in the seed 7 run and
positive in the seed 8 run, and on causality the file is explicit:
campaigns in this corpus were targeted by the retailer, not randomized; nothing here estimates what an offer causes. The causal offers exhibit in this project remains the Criteo randomized-uplift result.
The scale caveat travels with every number in this band. The corpus is
2,595,732 basket lines from about
2,500 households at a grocery retailer, against TabFormer's
24 million rows. These are basket lines rather than transactions: each row is one product on one receipt,
so the row count is larger than the number of shopping trips behind it by roughly the basket size, and
the event unit itself differs from TabFormer's card transactions. That is a second variable sitting
alongside protocol and corpus, so the negative household transfer here should not be read as a pure
corpus effect. It is a protocol replication on a small real corpus, not a scale
replication, and it is not card data and not card-network data. It settles that the method and the
protocol travel to a real corpus, and that the result they produce on that corpus differs from the result they produce here.
It leaves open real card data at Amex scale, which is what the Phase 1 gate in Section 8 exists
for.
Surprise, rarity and the scam gap
American Express has reported the lowest US credit card fraud rate among major networks for
19 straight years58, on a stack that runs 8 billion-plus automated risk decisions on over $1 trillion of volume59.
Nothing in this subsection improves on that, and nothing in it is a criticism of it. The gap we are
pointing at is one Amex's own fraud leadership has described in public: once the transaction controls
became good enough that bad actors struggled to make money against them, the attacks came back around to
scams and social engineering47. Singapore quantifies that shift. The police
report that 81.8% of reported scam cases in 2025 involved self-effected transfers,
where the account holder moves the money themselves after being deceived4. A
model trained to answer "was this really the cardholder" cannot see those cases, because the answer is
yes.
Singapore's Shared Responsibility Framework has been in force since
16 December 202446, and its scope should be stated
precisely rather than invoked loosely. The framework covers seemingly authorised
transactions, meaning a scammer obtained the account credentials and transacted, and it places a duty on
financial institutions to run real-time fraud surveillance when an account is drained of a material sum
quickly. Self-effected transfers, the larger class, sit outside that defined scope. As a result, the largest
category of scam loss in this market is the one that neither unauthorized-fraud scoring nor the payout
framework is built around, and the practical question is what signal a firm could run against it without
waiting for a labeled scam dataset that does not exist.
One such signal can be read directly from the backbone we already have. The model was pretrained with a
masked-field objective at a mask probability of 0.15, so it can be asked, with no retraining and no
fine-tuning, how surprised it is by a transaction. Mask one field of the scored transaction at a time,
take the negative log-likelihood of the value that was actually there, and sum across fields. That total
is the transaction's behavioural surprise given the account's own history. Pseudo-log-likelihood used
this way is Salazar and colleagues' recipe for scoring masked language models, ACL 2020. Masking every
field at once would be out of distribution for a model pretrained at 15 percent, so we do not do it, and
the results file records that decision rather than leaving it implied.
No fraud label enters that score, and the guarantee is structural rather than stated in prose. The
scoring code is handed the token array and nothing else, the label file is opened only after every score
exists and the hash of the score matrix has been recorded, and that hash is checked again when the
numbers are written. That is the purpose of the exercise: the score is a detector that could be deployed on
a population with no labels at all, which is the situation authorized-scam detection is currently in.
Label-free score · frozen checkpoint 300,000 scored transactions · 945 fraud positives · 391 held-out accounts · an uninformed ranking scores 0.00315 PR-AUC.
- ✓ no fraud label reaches the score
- ✓ labels opened only after every score exists
- ✓ label column excluded from the pretraining vocabulary
- ✓ account and card identifiers never in the vocabulary
- ✓ pretraining corpus truncated before the test window
- ✓ every scored row is post-cut, so none was pretrained on
Reading the comparison the way it landed: on PR-AUC the paired difference is 0.0056 with an interval of [-0.0391, 0.0506], spanning zero, so the two are not separated; on ROC-AUC the paired difference is -0.0345 with an interval of [-0.0523, -0.0159], below zero, so the control beats the model. The reading used for deployment is taken from the interval rather than from the point estimate.
the error flag on its own ranks fraud at 0.5085 ROC-AUC, which is why every score above is also reported with that field dropped; the share of scored rows with no prior transaction in the window is 0.00013; the share carrying at least one value the pre-cut vocabulary never saw is 0.8871, and both the model score and the counts control see those the same way; the unseen-calendar-year flag on its own ranks fraud at 0.5432 ROC-AUC, which is what the behavioural-only rows are there to price.
Full-mask variant: NOT SHIPPED. Masking every field of a row at once is out of distribution for a 15% mask-probability pretrain. Any such variant would have to be labelled separately.
seed 7 · data labels: synthetic · generated by scripts/fm/protection_pll.py --check-able · lightgbm 4.7.0 · numpy 2.5.2 · polars 1.43.2 · pyarrow 25.0.1 · python 3.12.3 · sklearn 1.9.0 · torch 2.13.0+cu130
This section addresses the question that determines whether any of this is worth deploying. A surprise score can be nothing more
than "this value is globally rare", so we built exactly that with no model in it: marginal token
frequencies fitted on pre-cut rows of accounts outside the test set, scored the same way and measured
the same way. On the same
300,000 scored transactions carrying
945 real fraud positives across
391 held-out accounts, the model's surprise score reaches
0.1338 PR-AUC and
0.9022 ROC-AUC against an uninformed baseline of
0.00315. The counts-only control reaches
0.1282 and
0.9367. Paired on identical rows, contextual
surprise minus global rarity is
0.0056
on PR-AUC with an interval of
[-0.0391, 0.0506] that
spans zero, and
-0.0345
on ROC-AUC with an interval of
[-0.0523, -0.0159] that
sits entirely below it. The model therefore does not beat counting on this task, and on the metric where the
intervals do separate it is behind. We report this finding directly rather than leading with a
number that the control beats.
The combination of the two scores does outperform both, and it also requires no labels: standardize the two scores over the
scored rows and add them, unweighted, with nothing fitted. That combination reaches
0.3296 PR-AUC and
0.9497 ROC-AUC, which is
0.2014
PR-AUC above global rarity alone, interval
[0.1480, 0.2450], and
0.1958
above contextual surprise alone, interval
[0.1654, 0.2227], both
clear of zero on both metrics. In queue terms, the top one percent of that combined ranking holds
0.5989 of the fraud positives against
0.3228 for rarity alone. The
deployable rule here is therefore rarity plus novelty rather than either one on its own, and the model contributes as the second term rather than the first.
What it buys. The result is a rule that costs almost nothing to run and requires no labels,
reported alongside the control that beats it. For a model risk committee, that pair is the reviewable
object: a candidate signal, the inexpensive baseline it has to be better than, and an interval indicating whether it
is. In our experience, work that reports only its favourable results takes longer to approve, not less.
Two controls are reported in the same table so that these results can be verified rather than assumed. TabFormer carries an
Errors? column that could plausibly co-occur with fraud, so every score is reported a second time with
that field dropped. On its own the error flag ranks fraud at
0.5085 ROC-AUC, which is close to
chance level, and dropping it moves the model score from
0.1338 to
0.1323 PR-AUC. The second control answers a
question our own diagnostics raised rather than one a reviewer had to ask. The vocabulary was fitted on
pre-cut rows, so a post-cut calendar year is an unknown token on
0.8631 of the scored rows,
and it is fair to ask how much of the surprise is that rather than behaviour. The behavioural-only rows
drop the calendar fields and the error flag and keep the six that describe what the transaction did.
The scores on those rows are higher rather than lower: the combined score there reaches
0.4133 PR-AUC with the top one
percent holding
0.6783 of the
positives, and the unseen-year flag on its own ranks fraud at only
0.5432 ROC-AUC. The verdict
does not move with the field set either: on all three, the control beats the model on ROC-AUC with an
interval clear of zero, the two are not separated on PR-AUC, and the unweighted combination beats the
control on both.
What prototype scale settles
It demonstrates that the recipe runs end to end and that the transfer question can be answered rigorously at prototype
scale. It does not demonstrate production performance at Amex: the data is synthetic, and we state that limitation explicitly on this page.
Each row is one full pretrain plus the same leakage-hardened transfer evaluation, on the axis shown, with the places the runs are not identical named in the card above. Points: a 3M row earliest-window subset (seed 7); a 10M row earliest-window subset (seed 7); the full 24.4M row corpus (seed 7, the main run above); a seed 1337 repeat of the full 24.4M row corpus as a seed stability check; the same events regrouped into merchant sequences (merchant axis, seed 7). Deltas are reported as obtained.
Pair retention, the null and its limits
The scaling card says settling the two-sided question needs a task that is not degenerate on the merchant
axis. We built one and ran it, and the design was committed before the first run.
The task is pair retention. Take every account and merchant pair that transacted at least once before the
corpus cut, and ask whether that same pair transacts again after it. That is the merchant-side question a
merchant embedding could plausibly carry, and unlike next category it is not settled by the merchant alone:
838,863 pre-cut pairs with a return rate of
0.1691. The split is entity-disjoint by merchant,
167,245 training merchants against
71,370 test merchants sharing
0. The baseline is deliberately strong:
it gets pair frequency and recency, the account's pre-cut activity, and the merchant's own pre-cut
transaction count, distinct-account count and recency, so the embedding has to beat a model that already
knows how busy and how recent the merchant is. Every feature reads pre-cut rows only and every label reads
post-cut rows only.
The result is a null, and we report it as such. Adding the merchant-axis embedding moves ROC-AUC by
0.000589, interval
[-0.000475, 0.001567], and PR-AUC by
0.002829, interval
[-0.000422, 0.006311]. Both point estimates are positive and
the PR-AUC interval comes close to clearing zero without doing it. We put the cardholder-axis merchant
embedding through the identical pipeline as a control, and it reads the other way on both metrics,
-0.000847 and
-0.001342, with intervals that also span zero. On
this task, at this scale, on this corpus, the merchant-axis backbone does not add measurable signal over a
pair-history baseline.
Two limitations would need to be addressed before the two-sided question could be considered settled. The merchant vector is pooled
over that merchant's whole pre-cut history and carries nothing specific to the account, so it can only help
through merchant-level structure the merchant counts miss; the account-side as-of vector, which is the half
most likely to carry a return signal, is not in this arm, and it is absent because this run was built to
stay on a laptop rather than because we decided it did not belong. And the split is merchant-disjoint only,
since cardholders cross merchant boundaries, which is the same caveat the merchant-axis pretraining run
carries.
838,863 pre-cut (account, merchant) pairs built from 24,386,900 transactions, of which 0.1691 transact again after the cut. Split entity-disjoint by merchant: 167,245 train merchants against 71,370 test merchants, sharing 0 merchants. Scored on 257,239 test pairs across 71,370 merchants, positive rate 0.1776. Bootstrap 1,000 resamples, clustered on the test merchant. Every feature reads pre-cut rows only and every label reads post-cut rows only; the embedding join left 0 test pairs without a merchant vector.
What it buys. Read commercially this is a sizing answer rather than a
disappointment. It says roughly how much corpus a two-sided backbone needs before it pays for the
compute, it keeps the two-sided claim out of the pitch until a merchant-native task supports it, and it
leaves that task already built and pre-registered for the next round rather than promised.
Five pretrains, headroom and the cap
The same pretrain recipe and the same leakage-hardened transfer evaluation, run at three corpus
sizes, on a second seed, and on a second grouping axis, with the places the runs are not identical
named below. All five points are in the table, reported as obtained.
The next-category gain is not significant at 3 million rows, where the interval spans zero. It clears
zero at 10 million and stays there at the full corpus on both seeds, so the gain emerges with corpus
size and then flattens rather than keeping on rising. The 3 million row point is also the only one
where the evaluation itself is smaller, at
430,084 training rows and
109,918 test rows against the
800,000 and
300,000 cap that binds at
every larger point, so its null is consistent with a corpus effect or with a smaller downstream
sample, and this table does not separate the two. Corpus size is not varied on its own here either:
the 3 million and 10 million row points are earliest-window subsets, and each one recomputes its own
time cut and builds its own vocabulary from the rows it holds, so the smaller runs also see an
earlier time window and a different vocabulary. A clean single-variable version holds the evaluation
window fixed and shares one vocabulary across every point. Both controls are pre-registered in
Section 8.
The baseline moves with the data as well, from
0.22 top-1 accuracy
at 3 million rows to
0.235 and
0.241 at the
full corpus, so the embeddings are adding to a target that is itself getting better.
On the fraud task the embeddings add PR-AUC exactly where the baseline has headroom, and that holds
at both of the corpus sizes where it has any. Those two points are not independent replications of
each other: the 3 million row corpus is an earliest-window subset of the 10 million row one, so the
smaller run's rows and its users are contained in the larger run's. Two separate pretrains scored on
disjoint test rows carries some evidential weight; it does not constitute two independent samples, and we
state this explicitly rather than leave the term unqualified. The baseline here never sees the backbone, so its own movement
across these rows is a property of the downstream evaluation rather than of the pretraining corpus.
The fraud test set carries
42 positives at 3
million rows, 322 at 10
million and 945 at the full corpus, so headroom
in this table means headroom on that evaluation. At 3 million rows PR-AUC moves from
0.485 to
0.551, and at 10
million from
0.638 to
0.904, delta CI
[0.2001, 0.3436] entirely above zero, on
322 positive test cases
in 300,000 scored transactions.
Both intervals sit above zero and both are in the table. AUC on the same task does not confirm it and
does not contradict it either: the fraud AUC delta spans zero at all five points in the table,
including that 10 million row point, where the point estimate is positive but the interval runs
[-0.0034, 0.0115]. We lead with
PR-AUC on fraud because positives are that rare, so AUC is carried by the negatives. On the record of
which decision came first: both metrics have been reported side by side since the first run and
neither was named the lead before results existed, so the reason for leading with PR-AUC is the one
just given rather than a pre-registration. One caveat on the
level: our evaluation keeps every fraud positive and thins the negatives to reach the row cap, so
wherever that cap binds, which is every point from 10 million rows up, the positive rate in the scored
set sits above the rate in the window it is drawn from and the PR-AUC levels here sit above what a
live queue would score. The 3 million row point is the one place the cap does not bind, so its rows
are unthinned. The comparison between the two arms is unaffected either way, since both arms are
scored on the same rows. The full-corpus null in the table above is
saturation rather than a failure of the embeddings: that baseline already scores
0.99389 PR-AUC, which leaves close to nothing to
add. Before reading the next-category curve above 10 million rows as flat, we note that
the 10 million and full-corpus deltas are not distinguishable from each other on their own intervals,
so what follows reads point estimates rather than a measured difference. Our reading of that curve
starts inside our own
pipeline rather than with the corpus: the evaluation cap named above binds at every point from 10
million rows up, so the downstream training and test samples stop growing while the pretraining
corpus keeps growing. A ceiling in the synthetic corpus is the other candidate, and this table does
not separate the two. The production-scale evidence in Section 3 (Visa's
TREASURE27, Nubank's nuFormer28) is the scale argument this table
cannot supply, and the Section 8 pilot re-measures it on real closed-loop data.
The merchant-axis row is the two-sided leg, and it is an honest negative. We pretrained on the same events
regrouped into merchant sequences, and it produced merchant-view embeddings, so the dual-axis
mechanism is implementable. On that row the split is entity-disjoint in merchants only, since
cardholders cross merchant boundaries, so it is a partial two-sided demonstration. Both of that row's
deltas are nulls, and leakage of that kind would flatter the embeddings rather than hide a gain, so
the negative below is the conservative reading.
What it does not show is a two-sided gain, because both evaluation tasks
are degenerate on that axis. A merchant's category is close to constant across its own transaction
sequence, so next category is trivial there by construction: the baseline alone scores
0.985 top-1,
leaving no room for a transfer signal to show up. Fraud leaves little room on that axis as well: the
baseline there already scores
0.972 PR-AUC, and
at that level this run cannot separate a ceiling from an absence of merchant-side signal for a label
defined on the cardholder. So the run
turns two-sided beats single-sided into a measured open question instead of an assertion, and
settling it needs merchant-native tasks. We built one and put the question to it, below.