diff --git a/manual/luatex-math.tex b/manual/luatex-math.tex
index cf0bb1737500f1d70cc83df303ce5506e7400391..c6e6db5bed84502579c579e327bfc2ad4e7f24cc 100644
--- a/manual/luatex-math.tex
+++ b/manual/luatex-math.tex
@@ -888,93 +888,93 @@ value direction will be taken into account.
 % % This kind of parameters relate to the fact that italic correction in \OPENTYPE\
 % % math is bound to fuzzy rules. So, control is the solution.
 
-\subsection {Script and kerning}
-
-\topicindex {math+kerning}
-\topicindex {math+scripts}
-
-If you want to typeset text in math macro packages often provide something \type
-{\text} which obeys the script sizes. As the definition can be anything there is
-a good chance that the kerning doesn't come out well when used in a script. Given
-that the first glyph ends up in a \prm {hbox} we have some control over this.
-And, as a bonus we also added control over the normal sublist kerning. The \lpr
-{mathscriptboxmode} parameter defaults to~1.
-
-\starttabulate[|c|l|]
-\DB value     \BC meaning \NC \NR
-\TB
-\NC \type {0} \NC forget about kerning \NC \NR
-\NC \type {1} \NC kern math sub lists with a valid glyph \NC \NR
-\NC \type {2} \NC also kern math sub boxes that have a valid glyph \NC \NR
-\NC \type {2} \NC only kern math sub boxes with a boundary node present\NC \NR
-\LL
-\stoptabulate
-
-Here we show some examples. Of course this doesn't solve all our problems, if
-only because some fonts have characters with bounding boxes that compensate for
-italics, while other fonts can lack kerns.
-
-\startbuffer[1]
-    $T_{\tf fluff}$
-\stopbuffer
-
-\startbuffer[2]
-    $T_{\text{fluff}}$
-\stopbuffer
-
-\startbuffer[3]
-    $T_{\text{\boundary1 fluff}}$
-\stopbuffer
-
-\unexpanded\def\Show#1#2#3%
-  {\doifelsenothing{#3}
-     {\small\tx\typeinlinebuffer[#1]}
-     {\doifelse{#3}{-}
-        {\small\bf\tt mode #2}
-        {\switchtobodyfont[#3]\showfontkerns\showglyphs\mathscriptboxmode#2\relax\inlinebuffer[#1]}}}
-
-\starttabulate[|lBT|c|c|c|c|c|]
-    \NC          \NC \Show{1}{0}{}         \NC\Show{1}{1}{}         \NC \Show{2}{1}{}         \NC \Show{2}{2}{}         \NC \Show{3}{3}{}         \NC \NR
-    \NC          \NC \Show{1}{0}{-}        \NC\Show{1}{1}{-}        \NC \Show{2}{1}{-}        \NC \Show{2}{2}{-}        \NC \Show{3}{3}{-}        \NC \NR
-    \NC modern   \NC \Show{1}{0}{modern}   \NC\Show{1}{1}{modern}   \NC \Show{2}{1}{modern}   \NC \Show{2}{2}{modern}   \NC \Show{3}{3}{modern}   \NC \NR
-    \NC lucidaot \NC \Show{1}{0}{lucidaot} \NC\Show{1}{1}{lucidaot} \NC \Show{2}{1}{lucidaot} \NC \Show{2}{2}{lucidaot} \NC \Show{3}{3}{lucidaot} \NC \NR
-    \NC pagella  \NC \Show{1}{0}{pagella}  \NC\Show{1}{1}{pagella}  \NC \Show{2}{1}{pagella}  \NC \Show{2}{2}{pagella}  \NC \Show{3}{3}{pagella}  \NC \NR
-    \NC cambria  \NC \Show{1}{0}{cambria}  \NC\Show{1}{1}{cambria}  \NC \Show{2}{1}{cambria}  \NC \Show{2}{2}{cambria}  \NC \Show{3}{3}{cambria}  \NC \NR
-    \NC dejavu   \NC \Show{1}{0}{dejavu}   \NC\Show{1}{1}{dejavu}   \NC \Show{2}{1}{dejavu}   \NC \Show{2}{2}{dejavu}   \NC \Show{3}{3}{dejavu}   \NC \NR
-\stoptabulate
-
-Kerning between a character subscript is controlled by \lpr {mathscriptcharmode}
-which also defaults to~1.
-
-Here is another example. Internally we tag kerns as italic kerns or font kerns
-where font kerns result from the staircase kern tables. In 2018 fonts like Latin
-Modern and Pagella rely on cheats with the boundingbox, Cambria uses staircase
-kerns and Lucida a mixture. Depending on how fonts evolve we might add some more
-control over what one can turn on and off.
-
-\def\MathSample#1#2#3%
-  {\NC
-   #1 \NC
-   #2 \NC
-   \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{f}$         \NC
-   \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{e}$    \NC
-   \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{ee}$   \NC
-   \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{\tf fluff}$ \NC
-   \NR}
-
-\starttabulate[|Tl|Tl|l|l|l|l|]
-    \FL
-    \MathSample{normal}{modern}  {\mr}
-    \MathSample{}      {pagella} {\mr}
-    \MathSample{}      {cambria} {\mr}
-    \MathSample{}      {lucidaot}{\mr}
-    \ML
-    \MathSample{bold}  {modern}  {\mb}
-    \MathSample{}      {pagella} {\mb}
-    \MathSample{}      {cambria} {\mb}
-    \MathSample{}      {lucidaot}{\mb}
-    \LL
-\stoptabulate
+% \subsection {Script and kerning}
+%
+% \topicindex {math+kerning}
+% \topicindex {math+scripts}
+%
+% If you want to typeset text in math macro packages often provide something \type
+% {\text} which obeys the script sizes. As the definition can be anything there is
+% a good chance that the kerning doesn't come out well when used in a script. Given
+% that the first glyph ends up in a \prm {hbox} we have some control over this.
+% And, as a bonus we also added control over the normal sublist kerning. The \lpr
+% {mathscriptboxmode} parameter defaults to~1.
+%
+% \starttabulate[|c|l|]
+% \DB value     \BC meaning \NC \NR
+% \TB
+% \NC \type {0} \NC forget about kerning \NC \NR
+% \NC \type {1} \NC kern math sub lists with a valid glyph \NC \NR
+% \NC \type {2} \NC also kern math sub boxes that have a valid glyph \NC \NR
+% \NC \type {2} \NC only kern math sub boxes with a boundary node present\NC \NR
+% \LL
+% \stoptabulate
+%
+% Here we show some examples. Of course this doesn't solve all our problems, if
+% only because some fonts have characters with bounding boxes that compensate for
+% italics, while other fonts can lack kerns.
+%
+% \startbuffer[1]
+%     $T_{\tf fluff}$
+% \stopbuffer
+%
+% \startbuffer[2]
+%     $T_{\text{fluff}}$
+% \stopbuffer
+%
+% \startbuffer[3]
+%     $T_{\text{\boundary1 fluff}}$
+% \stopbuffer
+%
+% \unexpanded\def\Show#1#2#3%
+%   {\doifelsenothing{#3}
+%      {\small\tx\typeinlinebuffer[#1]}
+%      {\doifelse{#3}{-}
+%         {\small\bf\tt mode #2}
+%         {\switchtobodyfont[#3]\showfontkerns\showglyphs\mathscriptboxmode#2\relax\inlinebuffer[#1]}}}
+%
+% \starttabulate[|lBT|c|c|c|c|c|]
+%     \NC          \NC \Show{1}{0}{}         \NC\Show{1}{1}{}         \NC \Show{2}{1}{}         \NC \Show{2}{2}{}         \NC \Show{3}{3}{}         \NC \NR
+%     \NC          \NC \Show{1}{0}{-}        \NC\Show{1}{1}{-}        \NC \Show{2}{1}{-}        \NC \Show{2}{2}{-}        \NC \Show{3}{3}{-}        \NC \NR
+%     \NC modern   \NC \Show{1}{0}{modern}   \NC\Show{1}{1}{modern}   \NC \Show{2}{1}{modern}   \NC \Show{2}{2}{modern}   \NC \Show{3}{3}{modern}   \NC \NR
+%     \NC lucidaot \NC \Show{1}{0}{lucidaot} \NC\Show{1}{1}{lucidaot} \NC \Show{2}{1}{lucidaot} \NC \Show{2}{2}{lucidaot} \NC \Show{3}{3}{lucidaot} \NC \NR
+%     \NC pagella  \NC \Show{1}{0}{pagella}  \NC\Show{1}{1}{pagella}  \NC \Show{2}{1}{pagella}  \NC \Show{2}{2}{pagella}  \NC \Show{3}{3}{pagella}  \NC \NR
+%     \NC cambria  \NC \Show{1}{0}{cambria}  \NC\Show{1}{1}{cambria}  \NC \Show{2}{1}{cambria}  \NC \Show{2}{2}{cambria}  \NC \Show{3}{3}{cambria}  \NC \NR
+%     \NC dejavu   \NC \Show{1}{0}{dejavu}   \NC\Show{1}{1}{dejavu}   \NC \Show{2}{1}{dejavu}   \NC \Show{2}{2}{dejavu}   \NC \Show{3}{3}{dejavu}   \NC \NR
+% \stoptabulate
+%
+% % Kerning between a character subscript is controlled by \lpr {mathscriptcharmode}
+% % which also defaults to~1.
+%
+% Here is another example. Internally we tag kerns as italic kerns or font kerns
+% where font kerns result from the staircase kern tables. In 2018 fonts like Latin
+% Modern and Pagella rely on cheats with the boundingbox, Cambria uses staircase
+% kerns and Lucida a mixture. Depending on how fonts evolve we might add some more
+% control over what one can turn on and off.
+%
+% \def\MathSample#1#2#3%
+%   {\NC
+%    #1 \NC
+%    #2 \NC
+%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{f}$         \NC
+%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{e}$    \NC
+%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{ee}$   \NC
+%    \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{\tf fluff}$ \NC
+%    \NR}
+%
+% \starttabulate[|Tl|Tl|l|l|l|l|]
+%     \FL
+%     \MathSample{normal}{modern}  {\mr}
+%     \MathSample{}      {pagella} {\mr}
+%     \MathSample{}      {cambria} {\mr}
+%     \MathSample{}      {lucidaot}{\mr}
+%     \ML
+%     \MathSample{bold}  {modern}  {\mb}
+%     \MathSample{}      {pagella} {\mb}
+%     \MathSample{}      {cambria} {\mb}
+%     \MathSample{}      {lucidaot}{\mb}
+%     \LL
+% \stoptabulate
 
 \subsection{Fixed scripts}
 
@@ -1055,51 +1055,51 @@ is divided by 1000 which is the usual way to mimmick floating point factors in
 
 \startsection[title={Math constructs}]
 
-\subsection {Unscaled fences}
-
-\topicindex {math+fences}
-
-The \lpr {mathdelimitersmode} primitive is experimental and deals with the
-following (potential) problems. Three bits can be set. The first bit prevents an
-unwanted shift when the fence symbol is not scaled (a cambria side effect). The
-second bit forces italic correction between a preceding character ordinal and the
-fenced subformula, while the third bit turns that subformula into an ordinary so
-that the same spacing applies as with unfenced variants. Here we show Cambria
-(with \lpr {mathitalicsmode} enabled).
-
-\starttexdefinition Whatever #1
-    \NC \type{\mathdelimitersmode = #1}
-    \NC \mathitalicsmode1\mathdelimitersmode#1\ruledhbox{\showglyphs\showfontkerns\showfontitalics$f(x)$}
-    \NC \mathitalicsmode1\mathdelimitersmode#1\ruledhbox{\showglyphs\showfontkerns\showfontitalics$f\left(x\right)$}
-    \NC \NR
-\stoptexdefinition
-
-\start
-    \switchtobodyfont[cambria]
-    \starttabulate[|l|l|l|]
-        \Whatever{0}\Whatever{1}\Whatever{2}\Whatever{3}%
-        \Whatever{4}\Whatever{5}\Whatever{6}\Whatever{7}%
-    \stoptabulate
-\stop
-
-So, when set to 7 fenced subformulas with unscaled delimiters come out the same
-as unfenced ones. This can be handy for cases where one is forced to use \prm
-{left} and \prm {right} always because of unpredictable content. As said, it's an
-experimental feature (which somehow fits in the exceptional way fences are dealt
-with in the engine). The full list of flags is given in the next table:
-
-\starttabulate[|c|l|]
-\DB value  \BC meaning \NC \NR
-\TB
-\NC \type{"01} \NC don't apply the usual shift \NC \NR
-\NC \type{"02} \NC apply italic correction when possible \NC \NR
-\NC \type{"04} \NC force an ordinary subformula \NC \NR
-\NC \type{"08} \NC no shift when a base character \NC \NR
-\NC \type{"10} \NC only shift when an extensible \NC \NR
-\LL
-\stoptabulate
-
-The effect can depend on the font (and for Cambria one can use for instance \type {"16}).
+% \subsection {Unscaled fences}
+%
+% \topicindex {math+fences}
+%
+% The \lpr {mathdelimitersmode} primitive is experimental and deals with the
+% following (potential) problems. Three bits can be set. The first bit prevents an
+% unwanted shift when the fence symbol is not scaled (a cambria side effect). The
+% second bit forces italic correction between a preceding character ordinal and the
+% fenced subformula, while the third bit turns that subformula into an ordinary so
+% that the same spacing applies as with unfenced variants. Here we show Cambria
+% (with \lpr {mathitalicsmode} enabled).
+%
+% \starttexdefinition Whatever #1
+%     \NC \type{\mathdelimitersmode = #1}
+%     \NC \mathitalicsmode1\mathdelimitersmode#1\ruledhbox{\showglyphs\showfontkerns\showfontitalics$f(x)$}
+%     \NC \mathitalicsmode1\mathdelimitersmode#1\ruledhbox{\showglyphs\showfontkerns\showfontitalics$f\left(x\right)$}
+%     \NC \NR
+% \stoptexdefinition
+%
+% \start
+%     \switchtobodyfont[cambria]
+%     \starttabulate[|l|l|l|]
+%         \Whatever{0}\Whatever{1}\Whatever{2}\Whatever{3}%
+%         \Whatever{4}\Whatever{5}\Whatever{6}\Whatever{7}%
+%     \stoptabulate
+% \stop
+%
+% So, when set to 7 fenced subformulas with unscaled delimiters come out the same
+% as unfenced ones. This can be handy for cases where one is forced to use \prm
+% {left} and \prm {right} always because of unpredictable content. As said, it's an
+% experimental feature (which somehow fits in the exceptional way fences are dealt
+% with in the engine). The full list of flags is given in the next table:
+%
+% \starttabulate[|c|l|]
+% \DB value  \BC meaning \NC \NR
+% \TB
+% \NC \type{"01} \NC don't apply the usual shift \NC \NR
+% \NC \type{"02} \NC apply italic correction when possible \NC \NR
+% \NC \type{"04} \NC force an ordinary subformula \NC \NR
+% \NC \type{"08} \NC no shift when a base character \NC \NR
+% \NC \type{"10} \NC only shift when an extensible \NC \NR
+% \LL
+% \stoptabulate
+%
+% The effect can depend on the font (and for Cambria one can use for instance \type {"16}).
 
 \subsection[mathacc]{Accent handling}
 
@@ -1570,48 +1570,59 @@ requested math family is used.
 
 \startsection[title={Goodies}]
 
-\subsection {Flattening: \lpr {mathflattenmode}}
-
-\topicindex {math+flattening}
-
-The \TEX\ math engine collapses \type {ord} noads without sub- and superscripts
-and a character as nucleus. and which has the side effect that in \OPENTYPE\ mode
-italic corrections are applied (given that they are enabled).
-
-\startbuffer[sample]
-\switchtobodyfont[modern]
-$V \mathbin{\mathbin{v}} V$\par
-$V \mathord{\mathord{v}} V$\par
-\stopbuffer
-
-\typebuffer[sample]
+\subsection {Obsolete}
 
-This renders as:
+Per TL 2026 the following primitives are \quote {ignored}. They were not used in
+two decades unless by \CONTEXT\ for exploring variants but we can do that
+differently now. Obsolete commands that trigger a warning: \typ {\mathoption},
+\typ {\mathitalicssmode}, \typ {\mathnolimitsmode}, \typ {\mathscriptboxmode},
+\typ {\mathscriptcharmode}, \typ {\mathflattenmode}, \typ {\mathdefaultsmode},
+\typ {\mathrulethicknessmode}, \typ {\mathdelimitersmode}. Also no longer used
+are the parameters \typ {\Umathnolimitsupfactor} and \typ
+{\Umathnolimitsubfactor}.
 
-\blank \start \mathflattenmode\plusone \getbuffer[sample] \stop \blank
-
-When we set \lpr {mathflattenmode} to 31 we get:
-
-\blank \start \mathflattenmode\numexpr1+2+4+8+16\relax \getbuffer[sample] \stop \blank
-
-When you see no difference, then the font probably has the proper character
-dimensions and no italic correction is needed. For Latin Modern (at least till
-2018) there was a visual difference. In that respect this parameter is not always
-needed unless of course you want efficient math lists anyway.
-
-You can influence flattening by adding the appropriate number to the value of the
-mode parameter. The default value is~1.
-
-\starttabulate[|Tc|c|]
-\DB mode \BC class \NC \NR
-\TB
-\NC  1   \NC ord   \NC \NR
-\NC  2   \NC bin   \NC \NR
-\NC  4   \NC rel   \NC \NR
-\NC  8   \NC punct \NC \NR
-\NC 16   \NC inner \NC \NR
-\LL
-\stoptabulate
+% \subsection {Flattening: \lpr {mathflattenmode}}
+%
+% \topicindex {math+flattening}
+%
+% The \TEX\ math engine collapses \type {ord} noads without sub- and superscripts
+% and a character as nucleus. and which has the side effect that in \OPENTYPE\ mode
+% italic corrections are applied (given that they are enabled).
+%
+% \startbuffer[sample]
+% \switchtobodyfont[modern]
+% $V \mathbin{\mathbin{v}} V$\par
+% $V \mathord{\mathord{v}} V$\par
+% \stopbuffer
+%
+% \typebuffer[sample]
+%
+% This renders as:
+%
+% \blank \start \mathflattenmode\plusone \getbuffer[sample] \stop \blank
+%
+% When we set \lpr {mathflattenmode} to 31 we get:
+%
+% \blank \start \mathflattenmode\numexpr1+2+4+8+16\relax \getbuffer[sample] \stop \blank
+%
+% When you see no difference, then the font probably has the proper character
+% dimensions and no italic correction is needed. For Latin Modern (at least till
+% 2018) there was a visual difference. In that respect this parameter is not always
+% needed unless of course you want efficient math lists anyway.
+%
+% You can influence flattening by adding the appropriate number to the value of the
+% mode parameter. The default value is~1.
+%
+% \starttabulate[|Tc|c|]
+% \DB mode \BC class \NC \NR
+% \TB
+% \NC  1   \NC ord   \NC \NR
+% \NC  2   \NC bin   \NC \NR
+% \NC  4   \NC rel   \NC \NR
+% \NC  8   \NC punct \NC \NR
+% \NC 16   \NC inner \NC \NR
+% \LL
+% \stoptabulate
 
 \subsection {Less Tracing}
 
@@ -1621,44 +1632,44 @@ Because there are quite some math related parameters and values, it is possible
 to limit tracing. Only when \type {tracingassigns} and|/|or \type
 {tracingrestores} are set to~2 or more they will be traced.
 
-\subsection {Math options with \lpr {mathdefaultsmode}}
-
-This option has been introduced because \LATEX\ developers wanted some of the
-defaults to be different from the ones that were set in stone when we froze
-\LUATEX. The default values are:
-
-\starttabulate[|l|c|c|]
-\DB                 \BC scanning \BC rendering \NC \NR
-\TB
-\NC radical/root    \NC cramped  \NC cramped   \NC \NR
-\NC under delimiter \NC cramped  \NC supstyle  \NC \NR
-\NC over delimiter  \NC cramped  \NC substyle  \NC \NR
-\NC delimiter under \NC cramped  \NC current   \NC \NR
-\NC delimiter over  \NC cramped  \NC current   \NC \NR
-\LL
-\stoptabulate
-
-When \type {\mathdefaultsmode} is larger than zero, we have:
-
-\starttabulate[|l|c|c|]
-\DB                 \BC scanning \BC rendering \NC \NR
-\TB
-\NC radical/root    \NC cramped  \NC cramped   \NC \NR
-\NC under delimiter \NC substyle \NC substyle  \NC \NR
-\NC over delimiter  \NC supstyle \NC supstyle  \NC \NR
-\NC delimiter under \NC current  \NC current   \NC \NR
-\NC delimiter over  \NC cramped  \NC cramped   \NC \NR
-\LL
-\stoptabulate
-
-It is outside the scope of this manual to discuss the rationale behind these
-defaults. The zero values date back from the early times. If needed you can
-explicitly set the style in the content argument.
-
-\subsection {Math options with \lpr {mathoption}}
+% \subsection {Math options with \lpr {mathdefaultsmode}}
+%
+% This option has been introduced because \LATEX\ developers wanted some of the
+% defaults to be different from the ones that were set in stone when we froze
+% \LUATEX. The default values are:
+%
+% \starttabulate[|l|c|c|]
+% \DB                 \BC scanning \BC rendering \NC \NR
+% \TB
+% \NC radical/root    \NC cramped  \NC cramped   \NC \NR
+% \NC under delimiter \NC cramped  \NC supstyle  \NC \NR
+% \NC over delimiter  \NC cramped  \NC substyle  \NC \NR
+% \NC delimiter under \NC cramped  \NC current   \NC \NR
+% \NC delimiter over  \NC cramped  \NC current   \NC \NR
+% \LL
+% \stoptabulate
+%
+% When \type {\mathdefaultsmode} is larger than zero, we have:
+%
+% \starttabulate[|l|c|c|]
+% \DB                 \BC scanning \BC rendering \NC \NR
+% \TB
+% \NC radical/root    \NC cramped  \NC cramped   \NC \NR
+% \NC under delimiter \NC substyle \NC substyle  \NC \NR
+% \NC over delimiter  \NC supstyle \NC supstyle  \NC \NR
+% \NC delimiter under \NC current  \NC current   \NC \NR
+% \NC delimiter over  \NC cramped  \NC cramped   \NC \NR
+% \LL
+% \stoptabulate
+%
+% It is outside the scope of this manual to discuss the rationale behind these
+% defaults. The zero values date back from the early times. If needed you can
+% explicitly set the style in the content argument.
 
-This command is now obsolete and triggers an error message. It was only meant
-for experiments.
+% \subsection {Math options with \lpr {mathoption}}
+%
+% This command is now obsolete and triggers an error message. It was only meant
+% for experiments.
 
 % % even more obsolete:
 
diff --git a/manual/luatex.pdf b/manual/luatex.pdf
index 7cd3ef89b89e85eb281b096de865eeeaeb1aead6..d77bc8975fc4806c28b8c3e041ea44b205a72f11 100644
Binary files a/manual/luatex.pdf and b/manual/luatex.pdf differ
diff --git a/source/texk/web2c/luatexdir/ChangeLog b/source/texk/web2c/luatexdir/ChangeLog
index 8e3248b66520034d9a98901e5d8ae1d879712929..16950e3ef92120788f16bc22a79613484308891e 100644
--- a/source/texk/web2c/luatexdir/ChangeLog
+++ b/source/texk/web2c/luatexdir/ChangeLog
@@ -1,3 +1,8 @@
+2025-03-20 Luigi Scarso  <luigi.scarso@gmail.com>
+	*  some more never used modes made obsolete + staircase kerns adapted (H.Hagen)
+	   LuaTeX 1.23.1
+
+
 2025-03-18 Luigi Scarso  <luigi.scarso@gmail.com>
 	*  LuaTeX 1.23.0
 
diff --git a/source/texk/web2c/luatexdir/lua/ltexlib.c b/source/texk/web2c/luatexdir/lua/ltexlib.c
index 8962a39f3089844e4563627363ba65bcc42bea94..f06dd0c90ad55b1e3a74109a42e0aa9aae25aca6 100644
--- a/source/texk/web2c/luatexdir/lua/ltexlib.c
+++ b/source/texk/web2c/luatexdir/lua/ltexlib.c
@@ -3564,6 +3564,21 @@ static int tex_getmodevalues(lua_State * L)
     return 1;
 }
 
+/*tex   
+    This setter is only there so that we can still generate older \CONTEXT\ documents (like 
+    articles and progress reports) that refer to some now obsolete commands. Some of these 
+    math control are still present in \LUAMETATEX\ but in a different way. In \LUATEX\ they
+    became obsolete in 2025 (prelude to TL 2026) because we (MS/HH) notices that they'd 
+    never been used anywhere else. 
+*/
+
+static int tex_permitmathobsolete(lua_State * L)
+{
+    permit_math_obsolete = lua_toboolean(L, 1);
+    formatted_warning("math","obsolete commands are %s", permit_math_obsolete ? "permitted" : "blocked" );
+    return 0;
+}
+
 /* till here */
 
 void init_tex_table(lua_State * L)
@@ -3687,6 +3702,8 @@ static const struct luaL_Reg texlib[] = {
     { "quittoks", quittoks },
     { "forcehmode", forcehmode },
     { "getmodevalues", tex_getmodevalues },
+    /* private */
+    { "permitmathobsolete", tex_permitmathobsolete },
     /* sentinel */
     { NULL, NULL }
 };
diff --git a/source/texk/web2c/luatexdir/luatex.c b/source/texk/web2c/luatexdir/luatex.c
index 06af964ea90a416f9ae26463f778506d73bf693a..f6566ba02576cb10fab47e4f78345343b96fea01 100644
--- a/source/texk/web2c/luatexdir/luatex.c
+++ b/source/texk/web2c/luatexdir/luatex.c
@@ -33,8 +33,8 @@
 */
 
 int luatex_version = 123;
-int luatex_revision = '0';
-const char *luatex_version_string = "1.23.0";
+int luatex_revision = '1';
+const char *luatex_version_string = "1.23.1";
 const char *engine_name = my_name;
 
 #include <kpathsea/c-ctype.h>
diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h
index 1b9dbac607af1822fa02787fb1c31ce24e237fc2..147375209acbc19f24e922523a1b101c4cc8ef6e 100644
--- a/source/texk/web2c/luatexdir/luatex_svnversion.h
+++ b/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -1,4 +1,4 @@
 #ifndef luatex_svn_revision_h
 #define luatex_svn_revision_h
-#define luatex_svn_revision 7675
+#define luatex_svn_revision 7676
 #endif
diff --git a/source/texk/web2c/luatexdir/tex/commands.c b/source/texk/web2c/luatexdir/tex/commands.c
index 8c4389c7ce6d498c7f8a709a80614e992dfcee65..65a6ec20d830ea339dd72cdb2284f0d79babd26c 100644
--- a/source/texk/web2c/luatexdir/tex/commands.c
+++ b/source/texk/web2c/luatexdir/tex/commands.c
@@ -54,10 +54,6 @@ void initialize_commands(void)
     primitive_tex("thickmuskip", assign_mu_glue_cmd, glue_base + thick_mu_skip_code, glue_base + thin_mu_skip_code);
     primitive_luatex("mathsurroundskip", assign_glue_cmd, glue_base + math_skip_code, glue_base);
     primitive_luatex("mathsurroundmode", assign_int_cmd, int_base + math_skip_mode_code, int_base);
-    primitive_luatex("mathscriptboxmode", assign_int_cmd, int_base + math_script_box_mode_code, int_base);
-    primitive_luatex("mathscriptcharmode", assign_int_cmd, int_base + math_script_char_mode_code, int_base);
-    primitive_luatex("mathrulethicknessmode", assign_int_cmd, int_base + math_rule_thickness_mode_code, int_base);
-    primitive_luatex("mathflattenmode", assign_int_cmd, int_base + math_flatten_mode_code, int_base);
     primitive_tex("output", assign_toks_cmd, output_routine_loc, local_base);
     primitive_tex("everypar", assign_toks_cmd, every_par_loc, local_base);
     primitive_tex("everymath", assign_toks_cmd, every_math_loc, local_base);
@@ -86,7 +82,6 @@ void initialize_commands(void)
     primitive_tex("predisplaypenalty", assign_int_cmd, int_base + pre_display_penalty_code, int_base);
     primitive_tex("postdisplaypenalty", assign_int_cmd, int_base + post_display_penalty_code, int_base);
     primitive_luatex("mathpenaltiesmode", assign_int_cmd, int_base + math_penalties_mode_code, int_base);
-    primitive_luatex("mathdelimitersmode", assign_int_cmd, int_base + math_delimiters_mode_code, int_base);
     primitive_tex("interlinepenalty", assign_int_cmd, int_base + inter_line_penalty_code, int_base);
     primitive_tex("doublehyphendemerits", assign_int_cmd, int_base + double_hyphen_demerits_code, int_base);
     primitive_tex("finalhyphendemerits", assign_int_cmd, int_base + final_hyphen_demerits_code, int_base);
@@ -177,7 +172,6 @@ void initialize_commands(void)
     primitive_luatex("exceptionpenalty", assign_int_cmd, int_base + exception_penalty_code, int_base);
     primitive_luatex("fixupboxesmode", assign_int_cmd, int_base + fixup_boxes_code, int_base);
     primitive_luatex("glyphdimensionsmode", assign_int_cmd, int_base + glyph_dimensions_code, int_base);
-    primitive_luatex("mathdefaultsmode", assign_int_cmd, int_base + math_defaults_mode_code, int_base);
     primitive_luatex("discretionaryligaturemode", assign_int_cmd, int_base + discretionary_ligature_mode_code, int_base);
     primitive_etex("partokencontext", assign_int_cmd, int_base + partoken_context_code, int_base);
     primitive_luatex("mathemptydisplaymode", assign_int_cmd, int_base + math_empty_display_mode_code, int_base);
@@ -804,11 +798,21 @@ void initialize_etex_commands(void)
     primitive_luatex("mathrulesfam", assign_int_cmd, int_base + math_rules_fam_code, int_base);
     primitive_luatex("synctex", assign_int_cmd, int_base + synctex_code, int_base);
 
-    /* obsolete: */
+    /*     
+        These are obsolete per TL 2026 because we decided to stick to the more traditional \TEX\ 
+        approach: less discussion, confusion and documentation that way. The primitives are not 
+        used in TL 2025 but we keep them for older documents that describe them (articles). 
+    */
 
     primitive_luatex("mathoption", option_cmd, 0, 0);
     primitive_luatex("mathitalicsmode", assign_int_cmd, int_base + math_italics_mode_code, int_base);
     primitive_luatex("mathnolimitsmode", assign_int_cmd, int_base + math_nolimits_mode_code, int_base);
+    primitive_luatex("mathscriptboxmode", assign_int_cmd, int_base + math_script_box_mode_code, int_base);
+    primitive_luatex("mathscriptcharmode", assign_int_cmd, int_base + math_script_char_mode_code, int_base);
+    primitive_luatex("mathflattenmode", assign_int_cmd, int_base + math_flatten_mode_code, int_base);
+    primitive_luatex("mathdefaultsmode", assign_int_cmd, int_base + math_defaults_mode_code, int_base);
+    primitive_luatex("mathrulethicknessmode", assign_int_cmd, int_base + math_rule_thickness_mode_code, int_base);
+    primitive_luatex("mathdelimitersmode", assign_int_cmd, int_base + math_delimiters_mode_code, int_base);
 
     /* */
 
diff --git a/source/texk/web2c/luatexdir/tex/equivalents.h b/source/texk/web2c/luatexdir/tex/equivalents.h
index 5ac1871ab66ac63fc78030eddff758ea069c5910..53ad6e85be960c2a1e7ec3ea8c726b8f799036b2 100644
--- a/source/texk/web2c/luatexdir/tex/equivalents.h
+++ b/source/texk/web2c/luatexdir/tex/equivalents.h
@@ -300,10 +300,10 @@ the |number_regs| \.{\\dimen} registers.
 #  define pre_rel_penalty_code 108
 #  define math_penalties_mode_code 109
 #  define math_delimiters_mode_code 110
-#  define math_script_box_mode_code 111
-#  define math_script_char_mode_code 112
+#  define math_script_box_mode_code 111 /* obsolete */
+#  define math_script_char_mode_code 112 /* obsolete */
 #  define math_rule_thickness_mode_code 113
-#  define math_flatten_mode_code 114
+#  define math_flatten_mode_code 114 /* obsolete */
 
 #  define copy_lua_input_nodes_code 115
 #  define suppress_primitive_error_code 116
@@ -662,11 +662,6 @@ extern halfword last_cs_name;
 #define pre_bin_op_penalty_par             int_par(pre_bin_op_penalty_code)
 #define pre_rel_penalty_par                int_par(pre_rel_penalty_code)
 #define math_penalties_mode_par            int_par(math_penalties_mode_code)
-#define math_delimiters_mode_par           int_par(math_delimiters_mode_code)
-#define math_script_box_mode_par           int_par(math_script_box_mode_code)
-#define math_script_char_mode_par          int_par(math_script_char_mode_code)
-#define math_rule_thickness_mode_par       int_par(math_rule_thickness_mode_code)
-#define math_flatten_mode_par              int_par(math_flatten_mode_code)
 #define null_delimiter_space_par           dimen_par(null_delimiter_space_code)
 #define disable_lig_par                    int_par(disable_lig_code)
 #define disable_kern_par                   int_par(disable_kern_code)
@@ -797,7 +792,6 @@ extern halfword last_cs_name;
 
 #define fixup_boxes_par                    int_par(fixup_boxes_code)
 #define glyph_dimensions_par               int_par(glyph_dimensions_code)
-#define math_defaults_mode_par             int_par(math_defaults_mode_code)
 #define math_eq_dir_mode_par               int_par(math_eq_dir_mode_code)
 #define discretionary_ligature_mode_par    int_par(discretionary_ligature_mode_code)
 #define partoken_context_code_par          int_par(partoken_context_code)
@@ -810,6 +804,17 @@ extern halfword last_cs_name;
 
 #define math_use_current_family_code 7
 
+/* obsolete */
+
+#define math_italics_mode_par        int_par(math_italics_mode_code)
+#define math_script_char_mode_par    int_par(math_script_char_mode_code)
+#define math_script_box_mode_par     int_par(math_script_box_mode_code)
+#define math_nolimits_mode_par       int_par(math_nolimits_mode_code)
+#define math_flatten_mode_par        int_par(math_flatten_mode_code)
+#define math_defaults_mode_par       int_par(math_defaults_mode_code)
+#define math_rule_thickness_mode_par int_par(math_rule_thickness_mode_code)
+#define math_delimiters_mode_par     int_par(math_delimiters_mode_code)
+
 /*
     #define box(A) equiv(box_base+(A))
     #define box(A) eqtb[box_base+(A)].hh.rh
diff --git a/source/texk/web2c/luatexdir/tex/maincontrol.c b/source/texk/web2c/luatexdir/tex/maincontrol.c
index 0b3dfe445eee09683b227d5a9e7cf822c1d24496..669242c39931245430661ce8ff7e6d335664c5a1 100644
--- a/source/texk/web2c/luatexdir/tex/maincontrol.c
+++ b/source/texk/web2c/luatexdir/tex/maincontrol.c
@@ -3581,6 +3581,64 @@ void assign_internal_value(int a, halfword p, int val)
                 word_define(p, val);
             }
             break;
+        /* */
+        case math_italics_mode_code:
+            if (permit_math_obsolete) {
+                if (math_italics_mode_par != val) {
+                    normal_warning("math", "\\mathitalicsmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+        case math_nolimits_mode_code:
+            if (permit_math_obsolete) {
+                if (math_nolimits_mode_par != val) {
+                    normal_warning("math", "\\mathnolimitssmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+        case math_script_char_mode_code:
+            if (permit_math_obsolete) {
+                if (math_script_char_mode_par != val) {
+                    normal_warning("math", "\\mathscriptcharmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+        case math_script_box_mode_code:
+            if (permit_math_obsolete) {
+                if (math_script_box_mode_par != val) {
+                    normal_warning("math", "\\mathscriptboxmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+        case math_flatten_mode_code:
+            if (permit_math_obsolete) {
+                if (math_flatten_mode_par != val) {
+                    normal_warning("math", "\\mathflattenmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+        case math_defaults_mode_code:
+            if (permit_math_obsolete) {
+                if (math_defaults_mode_par != val) {
+                    normal_warning("math", "\\mathdefaultsmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+        case math_delimiters_mode_code:
+            if (permit_math_obsolete) {
+                if (math_delimiters_mode_par != val) {
+                    normal_warning("math", "\\mathdelimitersmode is obsolete");
+                }
+                word_define(p, val);
+            }
+            break;
+            /* */
         default:
             word_define(p, val);
             break;
@@ -4317,8 +4375,12 @@ void initialize(void)
         max_dead_cycles_par = 25;
         math_pre_display_gap_factor_par = 2000;
         pre_bin_op_penalty_par = inf_penalty;
-        math_script_box_mode_par = 1;
-        math_script_char_mode_par = 1;
+        /* obsolete but kept for old documents */
+        math_script_box_mode_par = 1;  
+        math_script_char_mode_par = 1; 
+        math_flatten_mode_par = 1; 
+        math_defaults_mode_par = 1; /* was 0 in TL 2025 but set by latex to 1 */
+        /* */
         pre_rel_penalty_par = inf_penalty;
         compound_hyphen_mode_par = 1;
         escape_char_par = '\\';
@@ -4347,7 +4409,6 @@ void initialize(void)
         font_bytes = 0;
         px_dimen_par = one_bp;
         math_eqno_gap_step_par = 1000 ;
-        math_flatten_mode_par = 1; /* ord */
         var_fam_par = -1;
         cs_text(frozen_protection) = maketexstring("inaccessible");
         format_ident = maketexstring(" (INITEX)");
diff --git a/source/texk/web2c/luatexdir/tex/mlist.c b/source/texk/web2c/luatexdir/tex/mlist.c
index 5ca4e2abc1e6ea2c5c13ac378cd41e4110601a23..7922ac54a9f95c9db286330409ed56b0f2794338 100644
--- a/source/texk/web2c/luatexdir/tex/mlist.c
+++ b/source/texk/web2c/luatexdir/tex/mlist.c
@@ -19,14 +19,27 @@ LuaTeX; if not, see <http://www.gnu.org/licenses/>.
 
 /*tex
 
-    These are now obsolete:
+    These are now obsolete because we found otu that no one uses them. A few are used in \CONTEXT\ 
+    but we can deal with that. Most users moved on to \LUAMETATEX\ where we plenty of ways to 
+    control the engine. Some code is still present because we need it for legacy progress reports.
+
+    \starttyping
+    \mathoption
+    \mathitalicssmode
+    \mathnolimitsmode
+    \mathscriptboxmode
+    \mathscriptcharmode
+    \mathflattenmode
+    \mathdefaultsmode
+    \mathrulethicknessmode
+    \mathdelimitersmode
+    \stoptyping
+
+    Also no longer used are:
 
     \starttyping
     \Umathnolimitsupfactor
     \Umathnolimitsubfactor
-    \mathnolimitsmode
-    \mathitalicssmode
-    \mathoption
     \stoptyping
 
 */
@@ -137,6 +150,8 @@ LuaTeX; if not, see <http://www.gnu.org/licenses/>.
 
 */
 
+int permit_math_obsolete = 0;
+
 #define is_new_mathfont(A)   ((font_math_params(A) > 0))
 #define is_old_mathfont(A,B) ((font_math_params(A) == 0) && (font_params(A) >= (B)))
 #define assume_new_math(A)   ((font_math_params(A) > 0) && (font_oldmath(A) == 0))
@@ -3550,7 +3565,7 @@ static scaled find_math_kern(internal_font_number l_f, int l_c, internal_font_nu
         krn = (krn_l + krn_r);
         krn_l = math_kern_at(l_f, l_c, top_right_kern, corr_height_bot);
         krn_r = math_kern_at(r_f, r_c, bottom_left_kern, corr_height_bot);
-        if ((krn_l + krn_r) < krn)
+        if((krn_l + krn_r) >= krn) /* was < */
             krn = (krn_l + krn_r);
         return (krn);
     } else if (cmd == sub_mark_cmd) {
@@ -3562,7 +3577,7 @@ static scaled find_math_kern(internal_font_number l_f, int l_c, internal_font_nu
         krn = (krn_l + krn_r);
         krn_l = math_kern_at(l_f, l_c, bottom_right_kern, corr_height_bot);
         krn_r = math_kern_at(r_f, r_c, top_left_kern, corr_height_bot);
-        if ((krn_l + krn_r) < krn)
+        if((krn_l + krn_r) >= krn) /* was < */
             krn = (krn_l + krn_r);
         return (krn);
     } else {
@@ -3610,119 +3625,136 @@ static pointer attach_hkern_to_new_hlist(pointer q, scaled delta2, halfword subt
     the new fonts so eventualy there will be an option to ignore such
     corrections.
 
+    We used to use the base characters corner kerns (we only had cambria to test) 
+    but now use the ssty ones instead. 
+
+    In the following code the |\mathscriptcharmode| and |\mathscriptboxmode| are 
+    still present but they are obsolete. We keep them because older documentation 
+    can then be run. 
+
 */
 
 #define analyze_script(init,su_n,su_f,su_c) do { \
-    su_n = init; \
-    if (su_n != null) { \
-        if (math_script_char_mode_par > 0 && type(su_n) == math_char_node) { \
-            fetch(su_n); \
-            if (char_exists(cur_f, cur_c)) { \
-                su_f = cur_f; \
-                su_c = cur_c; \
-            } else { \
-                su_n = null; \
-            } \
-        } else if (math_script_box_mode_par > 0 && type(su_n) == sub_mlist_node) { \
-            su_n = math_list(su_n); \
-            while (su_n != null) { \
-                if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
-                    su_n = vlink(su_n); \
-                } else if (type(su_n) == simple_noad) { \
-                    su_n = nucleus(su_n); \
-                    if (type(su_n) == math_char_node) { \
-                        fetch(su_n); \
-                        if (char_exists(cur_f, cur_c)) { \
-                            su_f = cur_f; \
-                            su_c = cur_c; \
+    { \
+        int saved_cur_size = cur_size; \
+        if (cur_size < 2) ++cur_size; \
+        su_n = init; \
+        if (su_n != null) { \
+            if (math_script_char_mode_par > 0 && type(su_n) == math_char_node) { \
+                fetch(su_n); \
+                if (char_exists(cur_f, cur_c)) { \
+                    su_f = cur_f; \
+                    su_c = cur_c; \
+                } else { \
+                    su_n = null; \
+                } \
+            } else if (math_script_box_mode_par > 0 && type(su_n) == sub_mlist_node) { \
+                su_n = math_list(su_n); \
+                while (su_n != null) { \
+                    if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
+                        su_n = vlink(su_n); \
+                    } else if (type(su_n) == simple_noad) { \
+                        su_n = nucleus(su_n); \
+                        if (type(su_n) == math_char_node) { \
+                            fetch(su_n); \
+                            if (char_exists(cur_f, cur_c)) { \
+                                su_f = cur_f; \
+                                su_c = cur_c; \
+                            } else { \
+                                su_n = null; \
+                            } \
                         } else { \
                             su_n = null; \
                         } \
+                        break; \
                     } else { \
                         su_n = null; \
+                        break; \
                     } \
-                    break; \
-                } else { \
-                    su_n = null; \
-                    break; \
-                } \
-            } \
-        } else if (type(su_n) == sub_box_node) { \
-            su_n = math_list(su_n); \
-            if (su_n != null) { \
-                if (type(su_n) == hlist_node) { \
-                    su_n = list_ptr(su_n); \
                 } \
+            } else if (type(su_n) == sub_box_node) { \
+                su_n = math_list(su_n); \
                 if (su_n != null) { \
-                    if (math_script_box_mode_par == 2) { \
-                        while (su_n != null) { \
-                            if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
-                                su_n = vlink(su_n); \
-                            } else if (type(su_n) == glyph_node) { \
-                                if (char_exists(font(su_n), character(su_n))) { \
-                                    su_f = font(su_n); \
-                                    su_c = character(su_n); \
+                    if (type(su_n) == hlist_node) { \
+                        su_n = list_ptr(su_n); \
+                    } \
+                    if (su_n != null) { \
+                        if (math_script_box_mode_par == 2) { \
+                            while (su_n != null) { \
+                                if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
+                                    su_n = vlink(su_n); \
+                                } else if (type(su_n) == glyph_node) { \
+                                    if (char_exists(font(su_n), character(su_n))) { \
+                                        su_f = font(su_n); \
+                                        su_c = character(su_n); \
+                                    } else { \
+                                        su_n = null; \
+                                    } \
+                                    break ; \
                                 } else { \
                                     su_n = null; \
+                                    break; \
                                 } \
-                                break ; \
-                            } else { \
-                                su_n = null; \
-                                break; \
                             } \
-                        } \
-                    } else if (math_script_box_mode_par == 3) { \
-                        int boundary = -1; \
-                        while (su_n != null) { \
-                            if ((type(su_n) == boundary_node) && (subtype(su_n) == user_boundary)) { \
-                                boundary = boundary_value(su_n); \
-                                su_n = vlink(su_n); \
-                            } else if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
-                                su_n = vlink(su_n); \
-                            } else if ((boundary > -1) && (type(su_n) == glyph_node)) { \
-                                if (char_exists(font(su_n), character(su_n))) { \
-                                    su_f = font(su_n); \
-                                    su_c = character(su_n); \
+                        } else if (math_script_box_mode_par == 3) { \
+                            int boundary = -1; \
+                            while (su_n != null) { \
+                                if ((type(su_n) == boundary_node) && (subtype(su_n) == user_boundary)) { \
+                                    boundary = boundary_value(su_n); \
+                                    su_n = vlink(su_n); \
+                                } else if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
+                                    su_n = vlink(su_n); \
+                                } else if ((boundary > -1) && (type(su_n) == glyph_node)) { \
+                                    if (char_exists(font(su_n), character(su_n))) { \
+                                        su_f = font(su_n); \
+                                        su_c = character(su_n); \
+                                    } else { \
+                                        su_n = null; \
+                                    } \
+                                    break ; \
                                 } else { \
                                     su_n = null; \
+                                    break; \
                                 } \
-                                break ; \
-                            } else { \
-                                su_n = null; \
-                                break; \
                             } \
                         } \
                     } \
+                } else { \
+                    su_n = null; \
                 } \
             } else { \
                 su_n = null; \
             } \
-        } else { \
-            su_n = null; \
         } \
-    } \
-  } while (0) \
+        cur_size = saved_cur_size; \
+     } \
+ } while (0) \
+
 
 #define x_su_style(n,cur_style,su_style) \
     (noadoptionnosubscript(n) ? cur_style : su_style(cur_style))
 
+/*tex 
+
+    Here |subshift| and |supshift| are no longer used. We could remove them. 
+
+*/
+
 static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift)
 {
     pointer x, y, z;
-    scaled shift_up, shift_down, clr;
-    scaled delta1, delta2;
-    halfword sub_n, sup_n, subtyp;
-    internal_font_number sub_f, sup_f;
-    int sub_c, sup_c;
-    sub_n = null;
-    sup_n = null;
-    sub_f = 0;
-    sup_f = 0;
-    sub_c = 0;
-    sup_c = 0;
-    delta1 = it;
-    delta2 = 0;
-    subtyp = 0;
+    scaled shift_up = 0;
+    scaled shift_down = 0;
+    scaled clr = 0;
+    halfword sub_n = null;
+    halfword sup_n = null;
+    halfword subtyp = 0;
+    internal_font_number sub_f = 0;
+    internal_font_number sup_f = 0;
+    int sub_c = 0;
+    int sup_c = 0;
+    scaled delta1 = it;
+    scaled delta2 = 0;
     switch (type(nucleus(q))) {
         case math_char_node:
         case math_text_char_node:
diff --git a/source/texk/web2c/luatexdir/tex/mlist.h b/source/texk/web2c/luatexdir/tex/mlist.h
index dc08e0cdd6f1fcde4c34154087ce25b328506435..f009a726d3f0c629b0038d07a8037bad80f0df2d 100644
--- a/source/texk/web2c/luatexdir/tex/mlist.h
+++ b/source/texk/web2c/luatexdir/tex/mlist.h
@@ -24,6 +24,8 @@
 
 extern int cur_size;
 
+extern int permit_math_obsolete;
+
 extern halfword del_width;
 extern halfword del_height;
 extern halfword del_depth;
diff --git a/source/texk/web2c/luatexdir/tex/texmath.c b/source/texk/web2c/luatexdir/tex/texmath.c
index 3c069a5d6bfa67ca31d3af6684fcdc3800290be8..3bea665413038f8a510c3fffdb1ab57c310fa419 100644
--- a/source/texk/web2c/luatexdir/tex/texmath.c
+++ b/source/texk/web2c/luatexdir/tex/texmath.c
@@ -2123,12 +2123,17 @@ void close_math_group(pointer p)
     if (p != null && vlink(p) == null) {
         if (type(p) == simple_noad) {
             if (subscr(p) == null && supscr(p) == null) {
-                /*tex (subtype(p) == ord_noad_type) */
+                /*tex 
+                    In traditional \TEX\ this only happens for ordinary noads. Per TL 2026 this
+                    is now an undocumented features and eventually it might get dropped (unless 
+                    it makes some \CONTEXT\ \MKIV\ things more difficult. 
+                */
+             // int flatten = subtype(p) == ord_noad_type; /*tex traditional \TEX. */
                 int flatten = 0;
                 int modepar = math_flatten_mode_par;
                 switch (subtype(p)) {
                     case ord_noad_type :
-                        flatten = (modepar & 1) == 1;
+                        flatten = (modepar & 1) == 1; /* the default */
                         break;
                     case bin_noad_type :
                         flatten = (modepar & 2) == 2;