<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: zxpmail</title>
    <description>The latest articles on DEV Community by zxpmail (@zxpmail).</description>
    <link>https://dev.to/zxpmail</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3971221%2Ffda4417c-010a-42c4-9008-b16ca30960cf.png</url>
      <title>DEV Community: zxpmail</title>
      <link>https://dev.to/zxpmail</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zxpmail"/>
    <language>en</language>
    <item>
      <title>Split the Score Change, Then Credit the System</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Thu, 05 Nov 2026 12:26:21 +0000</pubDate>
      <link>https://dev.to/zxpmail/split-the-score-change-then-credit-the-system-267j</link>
      <guid>https://dev.to/zxpmail/split-the-score-change-then-credit-the-system-267j</guid>
      <description>&lt;h1&gt;
  
  
  Split the Score Change, Then Credit the System
&lt;/h1&gt;

&lt;p&gt;Picture a system that regenerates a plan and deploys it every round: product selection, parameters, scheduling all qualify. At the end of each round it receives a score — conversion, click-through, any business metric. When such a system is said to be "self-improving," the evidence is usually this: this round's score stands above last round's.&lt;/p&gt;

&lt;p&gt;But a rise or fall has two sources. The plan actually got better. Or the environment changed — the same shelf earns differently this week and next; the goods did not change, the shoppers and the competition did. From the change alone, the two sources cannot be told apart.&lt;/p&gt;

&lt;p&gt;This piece does three things. First, it gives the split: the difference between two rounds' scores equals an environment term plus a learning term — the environment term is the effect of the environment changing, the learning term is the effect of swapping the plan — and one extra evaluation per round computes it online. Second, it measures how wrong the un-split number gets, in a toy with known ground truth over 100 paired seeds: when the environment moves fast enough, more than nine seeds in ten show a falling score with a positive learning total; under fast movement in the plan's favor, half of all seeds show a rising score owed mainly to the environment; under slow random drift, 14% of seeds have the environment total exceed the learning total. Third, it lists the conditions the split needs to hold online.&lt;/p&gt;

&lt;p&gt;The conclusion up front: the sign of the round-over-round difference is by itself neither evidence that the system learned nor evidence that it failed. What to read are the two terms.&lt;/p&gt;

&lt;p&gt;Two sentences of background. The previous piece, &lt;a href="https://dev.to/zxpmail/keep-the-gate-downgrade-the-recursion-2ml0"&gt;Keep the Gate, Downgrade the Recursion&lt;/a&gt;, checked an article by the Taobao Flash Sale team about a store-decoration selection system, which included an eight-day A/B with a +0.34% relative lift (P2). That comparison ran candidate against baseline over the same stretch of time, split 50:50 by user, with the environment on the same side for both — it is not exposed to the confusion this piece discusses, and this piece does not estimate the environment's share in it; the number carries over from the previous piece's check. The comment thread under that piece left a question open: online, how do you tell "the experience helped" apart from "the environment happened to move our way"? This piece supplies that measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The score change is the sum of two terms
&lt;/h2&gt;

&lt;p&gt;Write the scoring terrain as T, the incumbent — the currently deployed plan — as x, and the evaluator as f, so f(T, x) reads: the score of plan x on terrain T. The raw change is this round's reading minus last round's:&lt;/p&gt;

&lt;p&gt;naive(t) = f(T_t, x_t) − f(T_{t−1}, x_{t−1}).&lt;/p&gt;

&lt;p&gt;It equals the sum of two terms.&lt;/p&gt;

&lt;p&gt;The environment term: the environment changed, the candidate stayed where it was.&lt;/p&gt;

&lt;p&gt;env(t) = f(T_t, x_{t−1}) − f(T_{t−1}, x_{t−1}).&lt;/p&gt;

&lt;p&gt;The learning term: the candidate was swapped, the environment held at this round.&lt;/p&gt;

&lt;p&gt;search(t) = f(T_t, x_t) − f(T_t, x_{t−1}).&lt;/p&gt;

&lt;p&gt;The identity naive = env + search holds algebraically. What is missing, to compute it, is the middle reading: last round's candidate, scored on this round's terrain. Online, that is one extra evaluation per round — re-score the candidate deployed last round under today's evaluator.&lt;/p&gt;

&lt;p&gt;A frozen candidate is read alongside. It stops searching after deployment and only takes readings. Its readings carry no learning term; they measure the environment alone.&lt;/p&gt;

&lt;p&gt;The re-score is charged to the system's own budget. From round 2 on, each round has 48 evaluations: one incumbent re-score, plus 47 fresh samples. The evaluation spent on the re-score is one the system does not search with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three arms and a drift, inside the toy
&lt;/h2&gt;

&lt;p&gt;The terrain and the searcher are the same family as inherit-versus-reset in the previous piece. The settings needed for reproduction: 6 dimensions, 12 Gaussian bumps, bump width 0.18, box [−1, 1]. The score is the maximum of the bumps at the point, with no observation noise. The searcher is a (4, 12) evolution strategy with a 1/5 step rule. Six rounds, 100 paired seeds. The three arms inside one seed share one terrain and one drift trajectory.&lt;/p&gt;

&lt;p&gt;Round 1 is identical across arms: one evaluation at the start, then 48 samples. The deployed point is x_1. From round 2 on, the deployed arm and the reset arm each spend 48 per round: one opening evaluation, then 47 fresh samples.&lt;/p&gt;

&lt;p&gt;The deployed arm carries its search state into the next round. A challenger replaces the incumbent only if it scores higher on today's terrain. The learning term on this arm is therefore greater than or equal to zero in every round. A candidate already seen as worse is not swapped in.&lt;/p&gt;

&lt;p&gt;The reset arm searches from scratch each round. Its one opening evaluation is symmetric with the deployed arm's incumbent re-score; both are charged inside their own 48.&lt;/p&gt;

&lt;p&gt;The frozen arm searches only in round 1, then reads x_1 and spends no search budget.&lt;/p&gt;

&lt;p&gt;At every round boundary, the scoring terrain shifts by one step; this movement is the drift. The drift starts at the boundary of round 2. Each bump moves along a unit direction by a step of δ, reflecting off the box walls. The direction is fixed at the first boundary and never changes after.&lt;/p&gt;

&lt;p&gt;Three settings of direction.&lt;/p&gt;

&lt;p&gt;Favorable drift, meaning it benefits the deployed plan: each bump points from its own center toward x_1. The reference point is the point deployed in round 1. Once the direction is fixed, it does not follow later incumbents.&lt;/p&gt;

&lt;p&gt;Adverse drift, the opposite: each bump points away from x_1.&lt;/p&gt;

&lt;p&gt;Random drift: the direction is drawn once per seed and then fixed. It is not aimed at x_1.&lt;/p&gt;

&lt;p&gt;δ takes 0.04, 0.16, and 0.48, plus one setting with no drift at all. Relative to the bump width 0.18, the three steps are about 0.22, 0.89, and 2.7 bump widths. By round 6, the cumulative displacement without reflection is 5δ.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expectations written into the script before the run
&lt;/h2&gt;

&lt;p&gt;Five expectations were written into the script's docstring, before this run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Under favorable drift at δ=0.48, the frozen arm's mean peak (highest reading over the six rounds, minus its start) is greater than 0, with a 95% interval excluding 0.&lt;/li&gt;
&lt;li&gt;At δ=0.48, the false-rise rate under favorable drift exceeds that under adverse drift, and the false-fall rate under adverse drift exceeds that under favorable drift. Both comparisons are paired by seed, with the interval of the difference excluding 0.&lt;/li&gt;
&lt;li&gt;The identity residual, in every cell and every round, is below 1e-9.&lt;/li&gt;
&lt;li&gt;At zero drift, the environment term and the frozen arm's change are 0 seed by seed, and the naive total equals the learning total, within 1e-12.&lt;/li&gt;
&lt;li&gt;A soft expectation, not counted toward pass or fail: in some random-drift cell, the false-rise rate is greater than 0.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first four held. The fifth met its own passing line. That line only requires greater than 0. The random-drift false-rise rates across the three cells are 14%, 2%, and 0% (δ from small to large). Greater than 0 appears in the first two cells; the δ=0.48 cell is 0.&lt;/p&gt;

&lt;p&gt;The zero-drift row caught two pairing errors — subtractions between readings that did not belong together — while the script was being built. The numbers below come from the run after the fixes. This row is what checks the instrument itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Illusions counted per seed, not spread across rounds
&lt;/h2&gt;

&lt;p&gt;Each seed is first summed over rounds 2 through 6, then reduced to a yes or a no. A cell has 100 seeds and therefore 100 such verdicts. The intervals are bootstrap percentile intervals over these 100 numbers, resampled 2000 times, at 95%. The per-seed arrays are kept in the results JSON.&lt;/p&gt;

&lt;p&gt;False rise illusion: the naive total is greater than 0, and the environment total exceeds the learning total.&lt;/p&gt;

&lt;p&gt;False fall illusion: the naive total is less than 0, and the learning total is greater than 0.&lt;/p&gt;

&lt;p&gt;The learning term on the deployed arm is never negative. False fall therefore mostly says: the naive total is negative, and this seed replaced its incumbent at least once in the five rounds. At large drift the rate runs high; the main cause is that the environment term is almost always negative. The replace-only-if-better-today rule sets which seeds qualify — learning above zero is equivalent to at least one replacement — it does not push the rate up itself. What the pre-registration compares is the difference between drift directions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Readings by cell
&lt;/h2&gt;

&lt;p&gt;Two things get established in this section. First, the score can be pushed up by environment movement alone: under favorable drift at δ=0.48, a candidate that never searched again after deployment peaked +0.858 above its start. Second, once the environment moves fast enough, a falling score is the default state while learning is still happening: at δ=0.48, under adverse and random drift, more than nine seeds in ten end with a negative naive total and a positive learning total. The remaining paragraphs are the boundaries and corroboration of these two sentences.&lt;/p&gt;

&lt;p&gt;The frozen peak is the frozen arm's highest reading over the six rounds minus its start. The frozen end is the round-6 reading minus the start. The naive, environment, and learning columns are seed means of the deployed arm's five-round totals, rounded to three decimals. Subtracting the learning column from the naive column in the same row may differ from the environment column by 0.001; that difference is rounding, not a mistake.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;drift&lt;/th&gt;
&lt;th&gt;δ&lt;/th&gt;
&lt;th&gt;frozen peak&lt;/th&gt;
&lt;th&gt;frozen end&lt;/th&gt;
&lt;th&gt;naive total&lt;/th&gt;
&lt;th&gt;env total&lt;/th&gt;
&lt;th&gt;search total&lt;/th&gt;
&lt;th&gt;false rise&lt;/th&gt;
&lt;th&gt;false fall&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0 (exact)&lt;/td&gt;
&lt;td&gt;0 (exact)&lt;/td&gt;
&lt;td&gt;+0.472&lt;/td&gt;
&lt;td&gt;0 (exact)&lt;/td&gt;
&lt;td&gt;+0.472&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;adverse&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;−0.073&lt;/td&gt;
&lt;td&gt;+0.337&lt;/td&gt;
&lt;td&gt;−0.133&lt;/td&gt;
&lt;td&gt;+0.470&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;15%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;random&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;+0.013&lt;/td&gt;
&lt;td&gt;−0.022&lt;/td&gt;
&lt;td&gt;+0.429&lt;/td&gt;
&lt;td&gt;−0.079&lt;/td&gt;
&lt;td&gt;+0.508&lt;/td&gt;
&lt;td&gt;14%&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;favorable&lt;/td&gt;
&lt;td&gt;0.04&lt;/td&gt;
&lt;td&gt;+0.292&lt;/td&gt;
&lt;td&gt;+0.292&lt;/td&gt;
&lt;td&gt;+0.552&lt;/td&gt;
&lt;td&gt;+0.061&lt;/td&gt;
&lt;td&gt;+0.491&lt;/td&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;adverse&lt;/td&gt;
&lt;td&gt;0.16&lt;/td&gt;
&lt;td&gt;+0.001&lt;/td&gt;
&lt;td&gt;−0.078&lt;/td&gt;
&lt;td&gt;−0.048&lt;/td&gt;
&lt;td&gt;−0.376&lt;/td&gt;
&lt;td&gt;+0.328&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;td&gt;78%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;random&lt;/td&gt;
&lt;td&gt;0.16&lt;/td&gt;
&lt;td&gt;+0.016&lt;/td&gt;
&lt;td&gt;−0.077&lt;/td&gt;
&lt;td&gt;−0.035&lt;/td&gt;
&lt;td&gt;−0.523&lt;/td&gt;
&lt;td&gt;+0.488&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;54%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;favorable&lt;/td&gt;
&lt;td&gt;0.16&lt;/td&gt;
&lt;td&gt;+0.791&lt;/td&gt;
&lt;td&gt;+0.377&lt;/td&gt;
&lt;td&gt;+0.261&lt;/td&gt;
&lt;td&gt;−0.199&lt;/td&gt;
&lt;td&gt;+0.460&lt;/td&gt;
&lt;td&gt;22%&lt;/td&gt;
&lt;td&gt;13%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;adverse&lt;/td&gt;
&lt;td&gt;0.48&lt;/td&gt;
&lt;td&gt;+0.005&lt;/td&gt;
&lt;td&gt;−0.078&lt;/td&gt;
&lt;td&gt;−0.068&lt;/td&gt;
&lt;td&gt;−0.142&lt;/td&gt;
&lt;td&gt;+0.075&lt;/td&gt;
&lt;td&gt;4%&lt;/td&gt;
&lt;td&gt;91%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;random&lt;/td&gt;
&lt;td&gt;0.48&lt;/td&gt;
&lt;td&gt;+0.015&lt;/td&gt;
&lt;td&gt;−0.078&lt;/td&gt;
&lt;td&gt;−0.074&lt;/td&gt;
&lt;td&gt;−0.287&lt;/td&gt;
&lt;td&gt;+0.213&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;favorable&lt;/td&gt;
&lt;td&gt;0.48&lt;/td&gt;
&lt;td&gt;+0.858&lt;/td&gt;
&lt;td&gt;+0.468&lt;/td&gt;
&lt;td&gt;+0.332&lt;/td&gt;
&lt;td&gt;+0.050&lt;/td&gt;
&lt;td&gt;+0.282&lt;/td&gt;
&lt;td&gt;50%&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the zero-drift row, both illusion rates are 0, and the naive total equals the learning total seed by seed. Across all cells, the largest identity residual is about 1.1e-16.&lt;/p&gt;

&lt;p&gt;Under favorable drift at δ=0.48, the frozen arm's peak is +0.858 above its start, interval [+0.836, +0.879]. The point is x_1, unmoved since deployment. The bumps were pushed toward where it sits; the rise in the reading comes from the terrain. Under adverse drift at the same speed, the peak is +0.005 [+0.002, +0.009], and the end is −0.078.&lt;/p&gt;

&lt;p&gt;The adverse cells all end below their start, at about −0.07 to −0.08. Their peaks sit near 0 or slightly above. The peak is the highest point across the six rounds; after a bump reflects off a wall, it can pass near x_1 again.&lt;/p&gt;

&lt;p&gt;This toy has no observation noise; all movement on the frozen arm comes from the terrain. Live readings carry noise. Taking a maximum over several noisy rounds biases the result upward. The identity uses per-round endpoint readings. The peak only says where the frozen arm got to across the six rounds.&lt;/p&gt;

&lt;p&gt;Favorable drift pushes the bumps toward x_1, and the frozen arm stands on x_1. The deployed arm leaves that point. Under the same favorable setting, the environment term on the incumbent can be negative.&lt;/p&gt;

&lt;p&gt;Favorable at δ=0.16 is such a case. The deployed arm's environment total averages −0.199, interval [−0.283, −0.113], excluding 0. The learning total is +0.460, the naive total +0.261. The cell is named favorable, and the incumbent's environment account is a deduction on average.&lt;/p&gt;

&lt;p&gt;Under favorable drift at δ=0.48, the environment total averages +0.050, interval [−0.058, +0.157], including 0. The learning total averages +0.282, above the environment total. The false-rise rate in this cell is 50% [40, 60]. The 50% says: in half the seeds, the environment total exceeded the learning total. That is not the same sentence as "the mean of the environment column exceeds the mean of the learning column." In this cell, the learning column's mean is larger.&lt;/p&gt;

&lt;p&gt;The pre-registered comparisons hold at δ=0.48. The false-rise rate under favorable drift exceeds adverse by 0.46 [+0.35, +0.56]. The false-fall rate under adverse drift exceeds favorable by 0.71 [+0.62, +0.80].&lt;/p&gt;

&lt;p&gt;Random drift does not aim at x_1. At δ=0.04, about 0.22 bump widths, the false-rise rate is 14% [8, 21]. The cell's naive total is +0.429, learning total +0.508, environment total −0.079. On most seeds, the naive sign matches the learning sign. The 14% are the false-rise seeds.&lt;/p&gt;

&lt;p&gt;As δ grows, random drift takes another shape. At δ=0.16, about 0.89 bump widths: naive total −0.035, learning total +0.488, false fall 54% [44, 64]. At δ=0.48, about 2.7 bump widths: naive total −0.074, learning total +0.213, false fall 95% [90, 99], false rise 0. These δ are already at the terrain's own scale.&lt;/p&gt;

&lt;p&gt;One more item was not in the pre-registration. It is the deployed arm's round-6 score minus the reset arm's round-6 score, asking whether carrying search state to the next round was worth anything.&lt;/p&gt;

&lt;p&gt;At zero drift the difference is +0.457 [+0.381, +0.537]. At δ=0.04, all three drift settings sit roughly between +0.34 and +0.53. Beyond that:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;drift&lt;/th&gt;
&lt;th&gt;δ=0.16&lt;/th&gt;
&lt;th&gt;δ=0.48&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;adverse&lt;/td&gt;
&lt;td&gt;−0.022 (interval crosses 0)&lt;/td&gt;
&lt;td&gt;−0.099 [−0.126, −0.074]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;random&lt;/td&gt;
&lt;td&gt;−0.041 [−0.061, −0.021]&lt;/td&gt;
&lt;td&gt;−0.071 [−0.090, −0.053]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;favorable&lt;/td&gt;
&lt;td&gt;+0.091 [+0.025, +0.156]&lt;/td&gt;
&lt;td&gt;+0.287 [+0.212, +0.363]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Adverse and random drift fall to around zero or below; under favorable drift the difference stays positive. This prices no component of a production system and no real experience store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditions that must hold to carry this online
&lt;/h2&gt;

&lt;p&gt;Inside the toy, the middle reading is given directly by the simulator, so the identity is exact. Carried online, the same subtraction needs all three of these.&lt;/p&gt;

&lt;p&gt;Both readings use the same ruler. If the evaluator changed versions between rounds, the ruler's change enters the environment term. Record the evaluator version next to every reading.&lt;/p&gt;

&lt;p&gt;Last round's deployed candidate must stay measurable. It is either still live, or replayable through the current evaluator exactly as it was frozen.&lt;/p&gt;

&lt;p&gt;The re-score is charged to the system's budget. A re-score placed outside the budget adds samples to the system.&lt;/p&gt;

&lt;p&gt;The reset control asks whether search state should carry to the next round. The split asks, of this round's increment, how much came from the environment and how much from replacing the candidate. Both fit inside one six-round run. The real cross-round A/B on real business was not run here and was not run in the previous piece.&lt;/p&gt;

&lt;p&gt;The remaining conditions are recorded here. The terrain is a toy, the score is a maximum of bumps, there is no A/B gate, and there is no business noise. The percentages in the table belong to this toy and these δ. δ is a length relative to the bump width 0.18; under another ruler it does not carry over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Three conclusions.&lt;/p&gt;

&lt;p&gt;The split works, and it is cheap. The round-over-round difference equals an environment term plus a learning term; filling in the middle cell online costs one incumbent re-score per round plus one reading of a frozen candidate, both charged to the budget.&lt;/p&gt;

&lt;p&gt;The un-split score misattributes at measurable rates when the environment moves. Under fast movement in the plan's favor (δ=0.48), half of all seeds show a rising score owed mainly to the environment; under adverse and random drift, more than nine seeds in ten end with a falling score and a positive learning total; under slow random drift, 14% of seeds have the environment total exceed the learning total. The rates belong to this toy; the shape belongs to any environment that moves. Under slow drift, most seeds' naive sign still matches the learning sign — the rate moves with speed, the confusion does not vanish.&lt;/p&gt;

&lt;p&gt;So the sign of the round-over-round difference is by itself neither evidence that the system learned nor evidence that it failed; when the environment moves, it mostly reflects the environment. What to read are the environment term and the learning term. Back to the question the comment thread left open — how to tell &lt;em&gt;the experience helped&lt;/em&gt; apart from &lt;em&gt;the environment happened to move our way&lt;/em&gt; — the answer is the measurement itself: with it, the two questions separate; without it, the rise and fall stays unattributed.&lt;/p&gt;




&lt;p&gt;The full run is at &lt;a href="https://github.com/zxpmail/blog/blob/main/agent-determinism-illusions/scripts/ratchet-attribution-test.py" rel="noopener noreferrer"&gt;scripts/ratchet-attribution-test.py&lt;/a&gt;. The results JSON keeps per-seed arrays for every cell. The rates and intervals above can be recomputed from the raw trials.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A note on sourcing: the article under discussion is in Chinese, published by the Taobao tech team; the linked page is a mirror. The relative P2 +0.34% cited here was checked against the source text during the previous piece; see that piece's sourcing note.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The numbers come from the same run as the Chinese draft, and the sections correspond one to one.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>experimentation</category>
      <category>statistics</category>
    </item>
    <item>
      <title>Keep the Gate, Downgrade the Recursion</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Mon, 02 Nov 2026 10:14:54 +0000</pubDate>
      <link>https://dev.to/zxpmail/keep-the-gate-downgrade-the-recursion-2ml0</link>
      <guid>https://dev.to/zxpmail/keep-the-gate-downgrade-the-recursion-2ml0</guid>
      <description>&lt;h1&gt;
  
  
  Keep the Gate, Downgrade the Recursion
&lt;/h1&gt;

&lt;p&gt;Eight days of a first online A/B, and store-level add-to-cart conversion (P2) was up 0.34% relative. That number is from &lt;em&gt;基于 RSI 架构的淘宝闪购店铺装修选品 Agent 实践&lt;/em&gt; ("A Store-Decoration Selection Agent for Taobao Flash Sale, Built as RSI").&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://53ai.com/news/AIdianshang/2026102980739.html" rel="noopener noreferrer"&gt;基于RSI 架构的淘宝闪购店铺装修选品Agent 实践&lt;/a&gt; (53AI mirror of the Taobao tech-team article; numbers below were checked against this text on 2026-11-03)&lt;/p&gt;

&lt;p&gt;The article says what the number is allowed to mean. It supports a staged business result. Whether several rounds of online experience keep improving the next search still needs its own experiment. Automatic write-back of those results is still being wired up.&lt;/p&gt;

&lt;p&gt;The engineering is worth copying. Parameter search is a loop you can audit, stop, and refuse to ship. The phrase "recursive self-improvement" should be lowered by one floor: the floor that has not been measured. A semantic layer is the longer road. It is not finished enough to cross search off the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The engineering is the honest part
&lt;/h2&gt;

&lt;p&gt;The opening already separates two results. Under a fixed budget, CMA-ES gets a higher average holdout score. In the first A/B, P2 is up 0.34% relative. The first supports a local feedback update. The second supports a staged business result. A higher offline score, the article says outright, does not prove a multi-round business gain.&lt;/p&gt;

&lt;p&gt;It also says the sentence most write-ups skip. Finishing one generation, finding one high-scoring candidate, and seeing one positive A/B answer different questions. Keeping the baseline when the evidence is thin is a legitimate outcome of the loop. That sentence is in the definition, not in a footnote.&lt;/p&gt;

&lt;p&gt;The early evaluator used aggregate features. Swap a product and the score barely moved. Search had nothing to update on. Later the inputs were expanded by slot, then built into Slot Expert. From the slot model to Slot Expert, the article's retention-test R² went from 0.0707 to 0.2341, and MAE from 0.1298 to 0.1166. The article limits those figures to prediction on that architecture log. The eval-set definition is not fully stated. Do not read them as a clean gain across generations.&lt;/p&gt;

&lt;p&gt;A swap test covered 1,000 store-days and 3,000 replacements. The input actually changed in 2,754 of them. After calibration, the same-score rate was 7.12%. Most real swaps move the prediction. A tie region remains.&lt;/p&gt;

&lt;p&gt;The online gate freezes a candidate, then runs the A/B. "Keep the baseline when the evidence is thin" is first a stated rule. One concrete decision matches it. An automatic boundary round lifted validation ranking by 0.427 percentage points, short of a preset 0.5. In the shared bins, the worst raw MAE got about 18.2% worse, past the tolerance. That round was not adopted, and no extra seeds were added.&lt;/p&gt;

&lt;p&gt;On scheduling, rules propose an executable plan first. Qwen may suggest a change only inside an allowed range. If the check fails, the run falls back to the rules. Whether the model earns its call cost over rules alone is listed as a comparison still to run. There is no separate result yet.&lt;/p&gt;

&lt;p&gt;The discipline is three constraints. The score has to tell candidates apart. The thing you ship has to be frozen. An update that does not clear the bar has to stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursion has two clocks
&lt;/h2&gt;

&lt;p&gt;The article defines recursion this way. This round's evaluation is written into the search distribution, the archive, and the experience store. The next round's candidate generator reads that state. The definition is complete. The evidence splits by clock.&lt;/p&gt;

&lt;p&gt;The inner clock is one offline search. The data window and the evaluator stay fixed. CMA-ES updates the sampling distribution from this batch of scores. The next batch is drawn from the updated distribution. The comparison turns off migration, experience guidance, and dynamic scheduling. The only difference is whether feedback updates the distribution. Four categories, 10 paired seeds. Average the categories with equal weight inside each seed, then pair the seeds. Random search gained +0.010593 on holdout. CMA-ES gained +0.014150. The difference is +0.003557, with a 95% paired interval of [+0.002089, +0.005234]. The drinks category alone has an interval that crosses zero. The advantage is in the final candidate, not in speed. The preset bar was the initial score plus 0.002. Mean evaluations to reach it were 5.300 for random search and 6.275 for CMA-ES. In 37 of 40 pairs, both sides had already cleared that bar inside the shared first batch. Inside this budget, updating the distribution buys a slightly better final holdout candidate. It does not show a faster hit, and it does not price multi-island search, migration, or experience one by one.&lt;/p&gt;

&lt;p&gt;The outer clock is the business loop. Freeze a candidate, run it online, then let that experience shape the next search. The first A/B covered four categories and about 40,000 stores, split 50:50 by user. Over eight days, store-level P2 was up 0.34% relative (p = 0.0389). Visit-to-order was up 0.46% relative. Store-entry to order was up 0.44% relative. The article is explicit. This is a staged gain for the whole package, in that scope and that window. It does not isolate one weight, one slot, or one search operator, and it is not a long-run result. Automatic write-back is not finished. To test value across rounds, compare "inherit the experience" with "reset the experience": same budget, and the only change is whether past feedback is used. That experiment was not run. The ending leaves it as the open question. Does carrying experience forward beat starting each round clean?&lt;/p&gt;

&lt;p&gt;Three sentences cover it. The 0.34% supports a staged gain for the whole package. The inner distribution update has a small offline increment. Cross-round inheritance has no separate evidence. Drop the outer loop and the evaluator, the freeze, the A/B, and the baseline rule still stand. The business number still has an explanation. Drop the inner distribution update and the holdout candidate is lower by 0.003557.&lt;/p&gt;

&lt;p&gt;The outer loop can still be worth something over a long horizon, if feedback reliably changes the next set of candidates and the environment is actually drifting. That takes the inherit-versus-reset experiment. It does not follow from an offline score and a single A/B.&lt;/p&gt;

&lt;p&gt;We ran a minimal analogue of that experiment, reproducible from this repo. Same budget on both sides, and the only change is whether past feedback is used: inherit the search state and archive versus reset each round, on a Gaussian-bump landscape with the drift speed swept, 100 paired seeds. The inheritance advantage falls with drift — +0.35 at zero drift, +0.22 at moderate drift, −0.01 with the interval crossing zero when the environment runs away — and at zero drift inheriting ties never stopping. That is the shape of the condition, not a number for their stack: the thresholds belong to this toy landscape, and nothing here prices a real A/B gate or their richer experience store (&lt;a href="https://github.com/zxpmail/blog/blob/main/agent-determinism-illusions/scripts/inherit-vs-reset-test.py" rel="noopener noreferrer"&gt;scripts/inherit-vs-reset-test.py&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  When the outer loop is too much machine
&lt;/h2&gt;

&lt;p&gt;The outer loop is probably too heavy when all of the following are true. Pinned items, capacity, and dedup squeeze the feasible set, so search saturates fast. The catalog, the traffic mix, and preferences move slowly, so one offline tune plus a scheduled review is enough. Eight days bought a 0.34% move, and another slower feedback layer will not wait. Operators have to say why these products, and a searched parameter bundle is often hard to explain. The evaluator is fixed and the window is short, so extra rounds can inflate the model score while the live metric stays flat.&lt;/p&gt;

&lt;p&gt;Under those conditions the practical setup is one search inside a budget, a person reading the result, a rerun on a schedule, and the gates this article already built. The swap test and the online A/B are there to stop score-hacking. They also show that closing the loop is not cheap.&lt;/p&gt;

&lt;p&gt;What stays fixed is usually the definition of P2, the category structure, and the constraint rules. The catalog, competitors, season, and user preference can move. The system is aimed at that second kind of change: the goal holds, the environment drifts, the strategy has to follow. When drift is fast and the combination space is large, search has a job. What has been measured is the small offline increment on the inner clock, plus one A/B of the whole package. Whatever the outer loop adds over "start clean each round" still has to be measured on its own. The difference between the two setups is drift speed and verification budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantics is the longer road
&lt;/h2&gt;

&lt;p&gt;A mature platform is missing a layer that makes products, scenes, constraints, and goals computable. Category and attributes. What pairs, and what substitutes. Traffic and campaigns. Capacity and compliance. Which local changes in P2 can actually be told apart. Once that layer is clear, selection can lean on constrained optimization, rules, and a scheduled recompute.&lt;/p&gt;

&lt;p&gt;The article puts the bottleneck on the whole feedback path. If the weights change and the assortment does not, the optimizer has nothing new to try. If the assortment changes and the score gap is not reliable, search has no direction. The early aggregate features were the second failure. Slots and Slot Expert put recent sales, exposure, clicks, add-to-cart, and image clarity on each position, so a local swap can enter the model. That supports a narrower claim: the model has to see the swap. Scene, pairing, intent, and local cause are a longer layer. They cross teams, and they are hard to write as rules. Eight days of online feedback is small and slow. Until the semantic layer exists, a bounded search still has to cover the part you cannot yet tell apart.&lt;/p&gt;

&lt;p&gt;Clearer semantics shrinks the space you have to search. Open the 10 exponents and the 2 diversity coefficients as well, and the continuous degrees of freedom reach 66. The article counts a parameter space, not a claim that every run searched every variable. Dedup and capacity sit beside that count. The space does not vanish because the semantics got clearer. Semantics can be the main road. Search stays on the residual that semantics still cannot separate, and that is worth a verification budget. The residual gets smaller. It is still there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules can take the explicit layer
&lt;/h2&gt;

&lt;p&gt;This is a sketch, not a result from the article.&lt;/p&gt;

&lt;p&gt;Explicit conditions fit an inverted index and rules: category, price, stock, time window, past hits. That layer is millisecond-scale and repeatable. Where rules do not cover, a typed judgment with a restricted output can return a probability and a branch. High confidence takes the automatic path. Low confidence goes back to a person or a conservative baseline. The model output does not execute itself.&lt;/p&gt;

&lt;p&gt;The article did not test an inverted index plus that kind of judgment API. The sketch is about whether a single decision stays controllable. If the inner search still runs, it still needs an evaluator, a candidate archive, and scheduler state. The two can sit together. A sketch is not a shipped design.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to take home
&lt;/h2&gt;

&lt;p&gt;Copy four engineering facts. The evaluator has to see a product swap. Freeze the candidate before the A/B. Stop an update that does not clear the bar. Let rules hold the publish gate. Lower the brand. "Recursive self-improvement" makes 0.34% sound like the accumulated gain of many self-improving rounds.&lt;/p&gt;

&lt;p&gt;The inner distribution update has a small offline result. Inheritance across online rounds does not. Semantics is worth building as the main road, and it is not finished enough to delete search. Drop the brand one floor. Keep the loop. Leave the unmeasured floor unmeasured.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;A note on sourcing: the article under discussion is in Chinese, published by the Taobao tech team; the linked page is a mirror. Quoted and paraphrased phrasing is my translation, and every number in this piece is reported as the source reports it — including the figures the source itself flags as limited (the retention-test R²/MAE pair and the "predictions on that architecture log" qualifier).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>architecture</category>
      <category>experimentation</category>
    </item>
    <item>
      <title>Wall, Ledger, Card: Wiring a Data-Fabricating Model into a Production ERP</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Tue, 27 Oct 2026 09:54:59 +0000</pubDate>
      <link>https://dev.to/zxpmail/wall-ledger-card-wiring-a-data-fabricating-model-into-a-production-erp-2f6i</link>
      <guid>https://dev.to/zxpmail/wall-ledger-card-wiring-a-data-fabricating-model-into-a-production-erp-2f6i</guid>
      <description>&lt;h1&gt;
  
  
  Wall, Ledger, Card: Wiring a Data-Fabricating Model into a Production ERP
&lt;/h1&gt;

&lt;p&gt;The test log holds one remarkably confident line: "Queried 2 accounting subjects."&lt;/p&gt;

&lt;p&gt;The speaker was our LLM. That round, not a single tool call went through — the agent platform's whitelist had failed silently, and the tools never reached it. It didn't error. It didn't stall. It fabricated an answer, complete with two subjects, in the tone of someone who had just run the query.&lt;/p&gt;

&lt;p&gt;The database showed zero calls that day.&lt;/p&gt;

&lt;p&gt;This is the scene nobody skips when wiring an AI assistant into enterprise systems: &lt;strong&gt;at least on the model we have in hand, it does not stop when the tools are missing — it fabricates an answer and keeps walking.&lt;/strong&gt; A pricier model, retries, more prompt engineering — would those help? We haven't verified it, and we wouldn't bet on it. Risk of this kind probably won't be eliminated by "smarter": the root isn't intelligence, it's that the talk, by nature, wants to tie itself into a neat bow.&lt;/p&gt;

&lt;p&gt;So the real problem was never "how do we make the model answer correctly." It was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to build a system where a data-fabricating model, on the MCP main path and the attack surfaces we enumerated, cannot hurt the database — where that fact can be mechanically verified and the boundary stated plainly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Session impersonation, file imports, scheduled jobs — not in that promise. The answer collapses into three words: wall, ledger, card.&lt;/p&gt;

&lt;p&gt;This is not a tutorial; it's field notes. The integration window was three days: a single-file MCP gateway, the cheapest tier model we could get, an open-source manufacturing ERP. The card registry, the first versions of the wall, and the agent platform all predate those three days; the three days were the window for wiring it onto the production path and writing the discipline in stone — not the schedule for inventing it from zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Lay of the Land
&lt;/h2&gt;

&lt;p&gt;The base is ERPNext v16 — about 500 business objects (doctypes) after stripping the dead ones. On top, our in-house agent platform mounts tools over MCP; each agent knows which surface it may use by a nameplate (an agent→tool-surface mapping). The model is the cheapest GLM tier — deliberately: what only holds on an expensive model isn't architecture, it's burning money.&lt;/p&gt;

&lt;p&gt;The user says "create a customer, Zhang San"; the assistant replies two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New customer "Zhang San", type: company.
1 confirm / 2 cancel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reply "1" and the database gains a row. The creator is not the assistant account — the assistant is read-only; real writes go through a separate executor account, and it acts only after confirmation completes. The audit ledger still records the assistant's orchestration chain: who released the row, who created the row — two ledgers. Reply "2" and nothing happens. That cut was forced by the direct-access hole in §4.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;MCP main path and the enumerated entity/method keys&lt;/strong&gt;: neither prompt-injection nor the model supplying its own confirmation words should land data that shouldn't be written. Side channels and the session layer: see the end.&lt;/p&gt;

&lt;p&gt;Two exams verify this, with different jobs that don't fight:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exam&lt;/th&gt;
&lt;th&gt;Tests what&lt;/th&gt;
&lt;th&gt;Counts as green by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Census&lt;/td&gt;
&lt;td&gt;Every object/method key in the registry hit once through MCP (one object or one method key = one "leg"; a leg is one test case)&lt;/td&gt;
&lt;td&gt;The audit ledger (mushy talk but complete ledger rows: close by the ledger, no retry to overturn)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scenarios&lt;/td&gt;
&lt;td&gt;Hard-coded short dialogs: pinned surface text + a database row&lt;/td&gt;
&lt;td&gt;Surface and database pass together&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In a scenario, if "1" comes back and no "created/cancelled" shows up, the executor replies 1 once more — what it sends is the confirmation surface, not a write request; the one-shot credential covers it, so this doesn't conflict with the no-blind-retry rule below. Counts are at the end. Here, only this: the census doesn't prove the model talks straight, and all-green scenarios don't prove the talk is accurate across five hundred objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Ledger: Never Trust the Talk
&lt;/h2&gt;

&lt;p&gt;The talk lies, and lies calmly. Beyond the opening fake subjects, two more flavors:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phantom receipts.&lt;/strong&gt; The model claims "confirmation received" when nothing arrived. A test bot that believed it and retried would send the same write twice; the write credential is one-shot, the second send burns it, and the real write fails. So it is nailed down: &lt;strong&gt;bots act only on audit rows; blind retries are forbidden.&lt;/strong&gt; "Received it," "approval clicked" — no engagement with any of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Double-send residue.&lt;/strong&gt; One turn, the tool call goes out twice: a mangled version gets rejected first, then a clean one passes. Two ledger rows. The consumer rule became "the last successful row wins" — if the last row is a rejection, that's not a win.&lt;/p&gt;

&lt;p&gt;Three planes, each keeping its own record:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plane&lt;/th&gt;
&lt;th&gt;Records what&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Audit ledger&lt;/td&gt;
&lt;td&gt;Gateway verdicts — release, reject, confirm-required, write-landed; one row each, with reason codes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wire dump&lt;/td&gt;
&lt;td&gt;The model's raw parameters, as sent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;The real rows and the creator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When end-to-end goes red: audit first, then the dump, verdict last. One suite run scored 19/20; a manual six-step replay (no model — requests walked through the wall by hand) proved the wall chain intact; the red was the model resending without the parameter literal. The discipline: &lt;strong&gt;wall correct, model noncompliant → model jitter, not a product defect.&lt;/strong&gt; With a reverse trigger: &lt;strong&gt;the same red shape recurring means turn around and suspect the wall.&lt;/strong&gt; Jitter is random; a regular red means the wall or the protocol is wrong under some fixed condition. "Model jitter" is not a permanent shield.&lt;/p&gt;

&lt;p&gt;Two small, hard rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Through the wall ≠ landed in the database.&lt;/strong&gt; Each keeps its own ledger; only after an independent WRITE row exists in the audit can green be told apart from green.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconcile against the right ledger.&lt;/strong&gt; After the domain split, each gateway writes its own audit file; grab the wrong ledger and even the green is fake.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And one more, often missed: &lt;strong&gt;a database assertion cannot tell who rejected.&lt;/strong&gt; A base-platform permission denial and a wall rejection look identical in the database. With multiple roles sharing one database, "returned 200" proves nothing. Assertions must assert down to the plane: which role's audit ledger it landed in, whether the creator is that domain's executor account. An assertion that doesn't name the plane is no assertion at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Card: Semantics Are Data, Not Code
&lt;/h2&gt;

&lt;p&gt;The model has to deal with ~500 objects; someone has to tell it what each object is, its fields, what's required. That is the semantic card.&lt;/p&gt;

&lt;p&gt;Domain research collects the cards; after culling the dead, merging, and gap-filling, the registry is finalized; dead surfaces go to a separate list. It later grew into six pieces: the blocklist, Chinese concept sentences, an alias table, the domain split, child-table snapshots, and a runtime merged registry. One sentence governs it all:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantics are data, not code.&lt;/strong&gt; Add an entity, change a domain, cull a dead surface, fill in a concept — edit a data file and restart; the gateway code doesn't move.&lt;/p&gt;

&lt;p&gt;Four pits forced that sentence out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dead-surface residue.&lt;/strong&gt; A batch of doctypes exist in site metadata but have no table in the database — abandoned residue from upstream. Touch one and it's an HTTP 500; desktop, API, and AI blow up together. The fix isn't interception code but a blocklist: at startup they are pulled from the registry and the permission shadow is deleted in sync; when upstream fixes it, pull the entry and restart. Substring matching nearly caused friendly fire: the list had "Bank Clearance," but the database still has a real child table, "Bank Clearance Detail."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The wildcard swallowed the config.&lt;/strong&gt; The night the domain-split file landed, startup logic merged by &lt;code&gt;card-*.json&lt;/code&gt; and swallowed a pure config file as an entity card; instances crashed in a flock. The rule: &lt;strong&gt;before any new data file enters, ask whether some glob will claim it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forgot the restart.&lt;/strong&gt; Data loads at startup. "I changed it, why no effect" — nine times out of ten, no restart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hand-copied contracts rot.&lt;/strong&gt; The per-domain skills (operating manuals for agents) carried hand-copied summaries of high-frequency contracts in v1. The registry iterated once and the copies rotted silently. Now they are generated views of the registry; &lt;code&gt;--check&lt;/code&gt; reports zero drift; hand-copying is banned. &lt;strong&gt;The registry is the single source of truth; two sources of truth equal none.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--check&lt;/code&gt; locks only &lt;strong&gt;internal&lt;/strong&gt; derivations against the registry. It cannot lock &lt;strong&gt;upstream&lt;/strong&gt;: after an ERPNext upgrade, fields, deprecations, and the dead-surface list all rot silently together. Upstream drift detection isn't built; it is on the books — the integration window can wire the registry, but who curates the registry long-term has no answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Wall: Trust the Model a Little Less Every Version
&lt;/h2&gt;

&lt;p&gt;The wall is the gateway's gatekeeper; every model request to the ERP passes through it. It governs four things: request shape, scenario whitelist, write confirmation, budget circuit-breaker. The philosophy in one line:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every version trusts the model a little less than the one before.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The jurisdiction, stated up front. Shape, whitelist, budget — reads pass too; objects off the registry cannot be read out, and the assistant is read-only anyway. Confirmation hangs only on writes. It does &lt;strong&gt;not&lt;/strong&gt; govern what happens after a read: not the retelling, not item names smuggled into it, not stored-type content in remarks. Excessive reads within the whitelist, sensitive fields fished out, database strings steering the model back — blank; see the end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V1, two-phase.&lt;/strong&gt; A write registers first and gets a one-shot credential → retold to the user → after consent, resent with the credential → the wall checks the digest and releases. It stops a malicious model, not an &lt;em&gt;orderly fool&lt;/em&gt;: without user consent, the model can supply the confirmation words itself. Reproduced in black and white in tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V2, three-phase.&lt;/strong&gt; Write authorization moved out of the LLM channel: on top of in-dialog confirmation, there had to be a registered document in the ERP that a human had clicked approved. Registration is always the assistant account; the "approved" state transition (colloquially, the flip) is allowed only from a session that isn't itself — the assistant approving its own registration gets a 417 from the base platform; the wall never even has to act. &lt;strong&gt;Malice without redemption power.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V3, back to single-factor.&lt;/strong&gt; The trigger was a user's one line: "why can't I understand this?" Out-of-band approval meant logging in and hunting for the document. Confirmation became "non-empty counts"; the talk is two lines, "1 confirm / 2 cancel"; reply 1 and it writes. Anti-forgery rests on: a one-shot credential, valid within ten minutes (the upper bound), and "rejected" as a veto; plus &lt;strong&gt;dwell&lt;/strong&gt; — a confirmation faster than the minimum interval is also rejected (the lower bound), against the model replying in milliseconds. Don't merge the two clocks into "dwell ten minutes"; the scenario that sleeps five seconds trips the lower bound. Out-of-band approval and non-empty-writes are two extremes; the middle forms — the confirmation echoing a digest a human can scan, a single-click confirmation link — never made the integration window's schedule, and were never tried.&lt;/p&gt;

&lt;p&gt;The document stays on as a record, with the "rejected" veto; nobody is asked to click in the system anymore. This defends against the model forging consent; it does &lt;strong&gt;not&lt;/strong&gt; defend against the channel being impersonated: a hijacker's 1 and a real user's 1 look identical to the wall; if rendering is poisoned to display "1 confirm," the wall cannot tell. The price is marked on the ledger: the session layer got no hardening in the window.&lt;/p&gt;

&lt;p&gt;Four iron rules, each with a story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permissions are the wall.&lt;/strong&gt; The assistant account bypassed the gateway and hit REST directly: create, modify, all 200 — the confirmation hook hung only on MCP. The fix wasn't a blocking script: the assistant was trimmed to read-only, writes go through the separate executor account, and without it configured, refuse. &lt;strong&gt;The wall's domain of definition must sit in the permission layer; hooks only guard the doors they can see.&lt;/strong&gt; The hole was found by probing; there may be doors not yet probed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gate obeys the same rules as the model.&lt;/strong&gt; The sales-order chain once ran six rounds with zero passes. At confirmation the model flattened a child-table array into a string — not tampering; it genuinely couldn't hold the array. Registration held an array, confirmation held a string, the digest went red; the model tried harder with the string — a type deadlock. The fix: both sides normalize stringified child tables back into arrays before computing the digest. &lt;strong&gt;An encoding ambiguity is not drift; a genuinely changed value is still rejected.&lt;/strong&gt; The protocol absorbs the peripheral's unreliability; it does not punish it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The receipt is external memory.&lt;/strong&gt; The confirmation receipt echoes the full payload for the model to copy. Demanding "resend verbatim" is dangerous — the model drifts back to its own previous draft. Anything that must be retold gets the full literal embedded in the talk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A failed flip must cry out.&lt;/strong&gt; The controller once allowed only approved→executed; a "1" takes pending→executed, and the 417 was swallowed silently — the write landed, the document hung in pending forever. Fixed the controller, and added a "flip failed" audit row. &lt;strong&gt;A silent failure costs more than a failure.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Four Expensive Silent Failures
&lt;/h2&gt;

&lt;p&gt;The split-and-merge went three rounds (roles vs. business surfaces, skills vs. nameplates, credential numbers). What is expensive is "one layer is lying while the others keep reporting green." Of the four, &lt;strong&gt;silently eating the old wall&lt;/strong&gt; and &lt;strong&gt;the same-name tool surface clobbering the last corner&lt;/strong&gt; are one family: the tests are green, the world has changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The credential war.&lt;/strong&gt; The general-domain tests went red in a row. First suspect: the model vendor; half a round, nothing. Then each credential in the config was fired at the database alone: 401. The wall's audit still said release (it checks the whitelist, not the base ticket); the talk offered one vague "authentication error." &lt;strong&gt;Of three layers, exactly one was telling the truth; attribution without per-layer verification lands wrong, every time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The assistant account was one key shared by several parties: whoever re-signs gets a working ticket, everyone else's dies. We re-signed, fixed ourselves, and killed the ticket another line had just synced; they wrote "the key was rotated out-of-band, not this repo's doing" — that was us. The discipline: &lt;strong&gt;on the next 401, try the other tickets in the config before re-signing.&lt;/strong&gt; The census now has its own user reusing the role permission shadow; the general assistant and the shared environment (colloquially, the cage) still share a key, unresolved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Silently eating the old wall.&lt;/strong&gt; The research directory defaulted to the main checkout. After a second checkout's new instances came up, they silently ate the main checkout's old wall — new prompts against old wall behavior, tests all green, but the write policy was wrong. A non-main checkout must be named explicitly in config. &lt;strong&gt;A silent misconfiguration costs an order of magnitude more than an error.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The same-name tool surface clobbering the last corner.&lt;/strong&gt; The general surface stood first; six business surfaces were split out later, each re-registering per domain. The registration name is a global single point; the last one registered wins — so for every leg run, the general surface got clobbered into that leg's domain surface. After the run, tests all green, but the "std registration" actually pointed at another domain. No error, no conflict notice — just a nameplate silently rewritten. The fix: independent surfaces, the std pinned in a PRE phase, auto-restore after the run. &lt;strong&gt;The family trait: the wall didn't break, the nameplate changed; and the green in the ledger hasn't yet heard the world moved.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tests deleted a real customer.&lt;/strong&gt; Cleanup once deleted by name — and hit a customer the user had created that very afternoon. He asked "creation succeeded but I can't find it"; two hours, three people, two answers, and one of them was our test. Cleanup became snapshot-difference: record the name set at start, delete only this run's additions. &lt;strong&gt;In an idempotency test, the deletion count should be zero.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One more from the same family: with the nameplate unpinned, the model called another party's surface — the wall never broke, and green cannot explain "the world already changed." Skills promising objects the wall doesn't recognize, not sweeping staging accounts before parallel runs, a resuming reconciler reading the full history at start — registered in the other ledger; not unfolded here.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Taming the Model and the Scenario Library
&lt;/h2&gt;

&lt;p&gt;Sample: one cheapest-tier GLM, three days of integration, limited turns. Field observation, not law; the lower bound holds only within the enumerated attack surfaces: on those surfaces, the least obedient peripheral can be fenced in, and a better-behaved one very likely too. The enumeration was drawn from this model's behavior; a smarter attack may land outside the enumeration — that is not in the lower bound.&lt;/p&gt;

&lt;p&gt;Hard pins: tool parameters must be object literals (a string silently becomes an empty object); one call per turn; an empty list is a real receipt, not a failure.&lt;/p&gt;

&lt;p&gt;Reproduced degradations: changing its story at confirmation and re-registering (a new credential); flattening arrays into strings; hallucinating "go click Approved in Desk"; inventing "ITEM-0001" as a shortcut; writing "1 confirm" as "1. confirm". There is a healthy window of roughly ten rounds; compliance fluctuates overnight, attribution unsettled.&lt;/p&gt;

&lt;p&gt;The master rule: &lt;strong&gt;the model is an unreliable peripheral.&lt;/strong&gt; Ask when in doubt; no fabrication, no self-supplied confirmation; prompts, gate wording, and persona lines share one source; &lt;strong&gt;the protocol leaves no room for improvisation — every improvised flourish ends up as an unattributable red row in the ledger.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The scenario library: declarative steps against "say this line → expected talk + expected database state"; adding a scenario costs zero code. Teardown: the ledger counts only this run's additions, pending documents cleared, snapshot-difference cleanup. Real defects caught in the first round: the relay line drifted in transcription (pinned to the literal); a "1" reply so fast it tripped the dwell lower bound (sleep five seconds — the bot learns to act human first); an old "defaults need confirmation" clause fighting the new protocol and bypassing registration. &lt;strong&gt;The scenario library is first a defect probe: green isn't the output; the red it catches is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Grit: the audit flush may lag the response by two seconds; leave half a second of tolerance at the dwell boundary; a fresh session number each round; don't assert a truncated "rejected" ("rejected by someone" won't match).&lt;/p&gt;

&lt;h2&gt;
  
  
  7. The Wrap
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The user says one thing
    → agent platform (one nameplate per surface, one skill per agent)
    → MCP gateway (six business surfaces + the census surface)
    → the wall (shape / whitelist / write-confirmation / budget; reads pass the first three; retelling ungoverned)
         ├ read: assistant read-only → ERP
         └ write: one-shot credential (≤10 min) + dwell floor → confirmed, then the executor account lands it
    → ERPNext (creator = executor account; audit = the assistant's orchestration chain; pending documents kept as records + the "rejected" veto)

Green trusts only audit rows and the database, never the talk.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The two exams (scale and policy; what each tests and what counts as green: §1)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exam&lt;/th&gt;
&lt;th&gt;Scale&lt;/th&gt;
&lt;th&gt;Policy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Census&lt;/td&gt;
&lt;td&gt;~1,376 legs (entities + method keys)&lt;/td&gt;
&lt;td&gt;Zero hard failures (wrong codes / transport dead / missed hits / wrongful writes); of these, 506 legs (~one third) had complete ledgers but mushy talk, closed by the ledger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scenarios&lt;/td&gt;
&lt;td&gt;84 items (plus a smaller demo/role matrix)&lt;/td&gt;
&lt;td&gt;Talk + database, both green across two rounds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Coverage is the MCP main path and the enumerated keys only. Imports, scheduled jobs, WebSockets were not hit one by one. REST direct access is not in the census; the §4 hole was found by probing, and the permission layer has its own probe now that it is patched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ledger is the only truth.&lt;/strong&gt; The talk fabricates, the model jitters, layers cross, the platform degrades silently — only each layer's audit rows let you still say "green" after hard failures hit zero. In full: on the MCP main path and the enumerated keys, the audit ledger is green; the ~one-third mushy talk is not in that sentence; scenarios are a different exam.&lt;/p&gt;

&lt;p&gt;Two more for anyone building this kind of system: the hardening direction is not a better model, it is moving trust out of the model; and assertions must name the layer — result codes lie.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the wall doesn't hold
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read-side talk&lt;/strong&gt;: it can keep unregistered objects from being read out; it cannot police smuggled retellings or fishing reads within the whitelist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation quality&lt;/strong&gt;: it protects the database, not the correctness of the talk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session and identity&lt;/strong&gt;: single-factor stops forged consent, not channel impersonation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upstream drift&lt;/strong&gt;: &lt;code&gt;--check&lt;/code&gt; cannot lock the database surface after an ERPNext upgrade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared keys&lt;/strong&gt;: the census has its own; the general assistant and the cage still share one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Silent platform degradation&lt;/strong&gt;: a missing whitelist or trailing junk on a config line downgrades without an error; unfixed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These six are not one kind of thing. Protecting the database but not the talk is a design boundary — it was never in the promise. Session hardening, shared keys, and silent degradation are debts the three-day window couldn't schedule; schedule them and they get paid. Fishing reads within the whitelist, upstream drift, and who curates the registry are registered questions without answers — being on the books is not a solution. Anyone copying this design copies all three along with the wall.&lt;/p&gt;

&lt;p&gt;The wall isn't eternal dogma either. If someday, on the same enumerated keys, the audit ledger and the database keep yielding reproducible evidence of "zero fabrication, zero out-of-bounds" — trusting the ledger, not the talk — then the confirmation layer owes a re-evaluation: downgraded, reshaped, or removed. Until that evidence exists, the confirmation layer stays at its current price. The wall's reason to exist is to be refuted by data, not kept by habit.&lt;/p&gt;

&lt;p&gt;That opening line — "Queried 2 accounting subjects" — is still lying in the test log. Every time someone asks "why not let the model touch the database directly," it comes back out.&lt;/p&gt;

&lt;p&gt;On the model we have in hand, it does not stop when the tools are missing.&lt;/p&gt;

&lt;p&gt;Your system has to stop for it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;A note on translation: this piece was written in Chinese; all quoted speech — the model's "Queried 2 accounting subjects," the user's "why can't I understand this?", the other team's log line — is translated, and the test logs and audit rows are the source of record. "Wall, ledger, card" (墙、账、卡) is the original mnemonic.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>aiagents</category>
      <category>erp</category>
    </item>
    <item>
      <title>Determinism Will Not Recover the Spec.</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Thu, 22 Oct 2026 12:22:41 +0000</pubDate>
      <link>https://dev.to/zxpmail/determinism-will-not-recover-the-spec-2jb9</link>
      <guid>https://dev.to/zxpmail/determinism-will-not-recover-the-spec-2jb9</guid>
      <description>&lt;h1&gt;
  
  
  Determinism Will Not Recover the Spec.
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;2026-10-23&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;People say this about rewriting an old system. The old system is deterministic. With the right method, it can be rebuilt completely. The first half holds. The second half has to change.&lt;/p&gt;

&lt;p&gt;Determinism means one thing. Given the input and the state, the output is fixed. It does not recover the spec. The hard part of the old code is what was never written down. Implicit behavior left by old patches. Compromises on the boundary. Defects that users already rely on. The reason for doing it that way, lost after the people left.&lt;/p&gt;

&lt;p&gt;The hard part of a rewrite is not the coding. Writing code is getting cheaper. What gets expensive is checking that the new system and the old one are the same thing, and finding a person who understands the old behavior and is allowed to say this may change. Before you check, write down three things. What you compare by. How large an input space you compare over. How sure you are right now. This piece is how those three become a process. The example only shows the shape. It is not a manual you can start work from.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Inventory the traces. Split them in two.
&lt;/h2&gt;

&lt;p&gt;The first step is not reading the code, and not inventing inputs. Inventory what the system already left behind. Missing logs are normal. The system is not invisible. Database state counts. Requests and responses upstream and downstream. Front-end events and support tickets. Queues and leftover files. Monitoring and packet captures, when they exist.&lt;/p&gt;

&lt;p&gt;These traces do not depend on someone who can explain the business. They depend on the system having recorded something. After the inventory, split them.&lt;/p&gt;

&lt;p&gt;Traces you can pair with an input and an output can become differential cases. Same input. Compare the two outputs. A trace that has only an outcome, and no input, only says that something happened here. The same row in a table can be left by many inputs. That trace is not a recovered spec. It says there is behavior here, and the input has not been found.&lt;/p&gt;

&lt;p&gt;Keep the two kinds apart, or the later cost is wrong. Outcome-only traces need a separate probe to recover the input. If you cannot recover it, register a gap. Do not write it up as a case.&lt;/p&gt;

&lt;p&gt;If there are no logs, no upstream or downstream records, no one who knows the business, and the code is too tangled to analyze, do not start by replacing the whole system. Strangle it. Move one function at a time at the edge. This is the same method on a smaller surface. Observe, diff, adjudicate, freeze a baseline. The surface is one that real traffic can hit. A method has to say how to do the work, and when not to replace the whole system.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Static analysis proposes. Observation confirms or kills.
&lt;/h2&gt;

&lt;p&gt;Each method has a blind spot. One of them is not enough.&lt;/p&gt;

&lt;p&gt;A person clicking only sees paths that person could imagine. A branch that exists in the code and was never triggered will not appear because you spent more time. Rare paths, error paths, and implicit behavior left by old patches sit outside the observer's imagination. Observation gives real samples. The boundary of the sample is the boundary of imagination.&lt;/p&gt;

&lt;p&gt;Static analysis can extract branches, conditions, constants, enums, state transitions, call chains, and external dependencies. It cannot recover business meaning. It cannot tell you whether a real input will reach a branch. It often cannot tell dead code from a hidden door. It gives structure. Structure is not behavior.&lt;/p&gt;

&lt;p&gt;Static analysis turns paths nobody thought of into hypotheses waiting to be checked. Observation confirms them or kills them. Do not make "at least one input per extracted branch" the task. Old code, dynamic languages, reflection, and implicit entry points fill that list with noise. If the denominator is the number of extracted branches, people will invent inputs for dead branches, and noise will pull the confidence down.&lt;/p&gt;

&lt;p&gt;The loop that holds:&lt;/p&gt;

&lt;p&gt;Extract the structure of behavior. Treat it as hypotheses. The aim is an objective structure. Understanding the business can wait.&lt;/p&gt;

&lt;p&gt;Design inputs for hypotheses that look like real branches. Boundaries and errors first.&lt;/p&gt;

&lt;p&gt;Run them. Record input, output, and the judgment. Put that into the differential cases.&lt;/p&gt;

&lt;p&gt;Check back. Which hypotheses were confirmed. Which observation overturned. Which are unreachable. Which no input has hit yet. Which are only provisional.&lt;/p&gt;

&lt;p&gt;Anything no input has hit is a risk. Do not write it down as absent. Do not count it as covered.&lt;/p&gt;

&lt;p&gt;A judgment of unreachable needs a basis. It counts as closed only when the basis says this: no entry on the call chain of this version, and reflection and external triggers have been checked. If the basis stops at "this static call chain shows no entry," mark it provisional. A provisional call is not closed. It is also not "no input designed yet." An input you have not built, and an entry you have not confirmed, are different. List provisional calls on their own, with a condition for review.&lt;/p&gt;

&lt;p&gt;Accuracy is not the value of static analysis. The value is that unthought paths become hypotheses you can kill. When observation overturns a hypothesis, the guess in the code and the old behavior disagree. Why they disagree is classified in section 4. Do not switch the new system over to the observation here.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Write the equivalence standard before you pick a method.
&lt;/h2&gt;

&lt;p&gt;The new code passing its own tests does not mean the behavior matches. High coverage only means a path was reached. It does not mean the path was right. When generated tests check generated code, the judge and the athlete are separate only if the mechanism, the context, and the standard are different. One generation process used on both sides is self-certification.&lt;/p&gt;

&lt;p&gt;Write the standard first. Pick the method after. Do not demand all four kinds on every module. Choose per module, and write the choice down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output match.&lt;/strong&gt; Same input, same returned result. This fits interfaces close to pure functions. This kind defaults to recovering the old behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side-effect match.&lt;/strong&gt; Writes to the database, messages sent, calls to external systems: same content, same order. This fits stateful parts. This kind also defaults to recovering the old behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timing.&lt;/strong&gt; Response time, concurrency, and retries fall inside a range you wrote down. That range is usually a service level you are willing to sign now. It is not a number read out of the old system. The old system may be slower. It may also be fast where nobody promised speed. Decide the allowed gap first. Then compare.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error behavior.&lt;/strong&gt; On bad input, compare the error code, the error message, and whether the fallback matches. An old error may be a compromise left on purpose. It may be an accidental defect. A match is compatibility. A change is a business decision. Classify first. Then decide whether to follow it.&lt;/p&gt;

&lt;p&gt;When the first two conflict, the business side ranks them in advance. Do not decide in the middle of testing. For the last two, the acceptable range is itself the result of a decision. Calling all four "equivalence" mixes recovered behavior with a standard you just set.&lt;/p&gt;

&lt;p&gt;Methods, cheap to expensive. Contract tests read the interface that was written down. Differential tests feed the same inputs to both sides and compare outputs. Shadow runs copy real traffic to the new system. Users still hit the old one. The new results are recorded and not returned. Formal proof is for a few modules. It proves a containment relation with the old behavior. Most modules will not get there, and do not need to. Proof is not the end of convergence.&lt;/p&gt;

&lt;p&gt;Pick by the risk of the module. The whole system does not need one method.&lt;/p&gt;

&lt;p&gt;A difference is not a failure. It is an error signal. Measure it. Sort by business impact. Close the high-impact ones first. Register low-impact ones as known deviations. The difference here is the old system and the new one disagreeing on the same input. A code hypothesis disagreeing with the old system is a separate ledger. Section 4 says how to classify after an overturn, how to gather evidence when you cannot tell, and when to stop gathering. Section 5 says how to schedule the adjudicator. "Sort by impact" replaces neither.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. After an overturn, classify. If you cannot tell, gather evidence, and write down when to stop.
&lt;/h2&gt;

&lt;p&gt;Static analysis can say the path exists. Observation can say what the path actually returns. Together they still cannot say whether this is a business promise. Observed behavior is not a promise by itself.&lt;/p&gt;

&lt;p&gt;The person in this role needs both. They understand what the old behavior means in the business. They have the authority to decide whether it may change. Those two often sit in different people. On a legacy system, the expensive part is often finding that person, not writing the new code.&lt;/p&gt;

&lt;p&gt;Keep the seats apart. A product owner can change an external promise, and often does not remember why an old defect was left. A domain expert knows why. After they leave, the people who remain often cannot sign. Customer success knows what users rely on, and usually cannot change a contract alone. The engineer writing the new system does not hold either seat. They do not both play and declare the two systems equivalent.&lt;/p&gt;

&lt;p&gt;When the two seats are different people, the person who understands explains, and the person with authority signs. The signature belongs to the product owner, or to whoever now owns that line of business. The person who understands may be a domain expert still around, or someone who can match a complaint to the old behavior. A person who cannot sign does not turn "I remember it used to work this way" into a decision.&lt;/p&gt;

&lt;p&gt;After observation overturns a code hypothesis, classify before you keep it, change it, or leave it open. The entries are different. Do not collapse them into "look it up and file it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intentional compromise.&lt;/strong&gt; Someone knew it would do this, and left it because of another constraint. Users or downstream systems may already rely on it. The entry is evidence of intent: an old decision, the constraint at the time, a person still here who can say why it was left. A signature to keep it keeps a promise. A signature to change it is a new business decision, and it names who is affected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;De facto commitment.&lt;/strong&gt; Nobody can show it was intended. Someone now uses this result to finish the next job. The entry is a fact of reliance. Intent evidence is optional. A signature to keep it keeps existing reliance. The record says there is no evidence of intent, the commitment comes from use, and it names the job and the kind of person. Changing it names who is affected. Do not file this class as an intentional compromise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accidental defect.&lt;/strong&gt; Nobody intended it. Nobody uses it to get work done, or using it causes harm. There is one entry. Someone explicitly claims it was a mistake, and can give the grounds for those two sentences. A signature to keep it inherits a defect. The record must say "inherited defect." It must name when the transition stops. Under this class, the default is not to follow the observation. Keeping it needs a separate reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unsettled.&lt;/strong&gt; The people here cannot say why. The facts of reliance do not point at a specific person and a specific next job. The only evidence is "the code does this," or "this happened and someone reported it." That stays open. Production doing it does not promote a defect into a promise.&lt;/p&gt;

&lt;p&gt;The evidence ladder does not produce an accidental defect. When the cheap paths are done and still show no reliance, stop on the lines below, as long-term open or as a known deviation. "We found no reliance" does not fill the accidental-defect class. Without that explicit claim, leave the class empty.&lt;/p&gt;

&lt;p&gt;Write the basis on the same record. Who claims it. Whether the basis is an old decision, reliance inside tickets, special handling downstream, or code alone. Code alone, with nobody who can state the intent and no reliance you can point at, is unsettled.&lt;/p&gt;

&lt;h3&gt;
  
  
  When it is unsettled, gather evidence. Write three lines for stopping.
&lt;/h3&gt;

&lt;p&gt;Do not wait for someone who remembers. They may never appear. Push unsettled toward a class you can sign. You are looking for two things. Was there intent. Does someone use this result to finish the next job.&lt;/p&gt;

&lt;p&gt;Cheap to expensive:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tickets.&lt;/strong&gt; Read which kind of thing the ticket says. Someone used this result to finish the next job. A manual replacement order, a reconciliation, a way around another process. That is reliance. Someone reported that this should not have happened. That is an objection. An objection says you should not keep the behavior as it stands. It does not support a de facto commitment. Read the support script the same way. It either confirms the behavior is expected, or it apologizes and routes around it. Only the first kind, and only when it keeps showing up, supports reliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upstream and downstream contracts.&lt;/strong&gt; If a caller or a downstream system has special handling or a special branch for this behavior, the behavior is an interface promise in fact, whether or not it was intended. A downstream system that accepts the result and does not distinguish this path has not blocked it. Failure to block is not a contract that the path must continue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data distribution.&lt;/strong&gt; How many records, how often, whether it clusters on a customer or a period. Volume does not classify. It decides whether more cost is worth spending.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shadow run.&lt;/strong&gt; Run both. The new system emits what the code hypothesis says. Users still hit the old system. Watch whether downstream systems and users report a break. A report counts when you can point at whose next job broke. Then the behavior is relied on. No report does not make it a defect. It means current traffic did not hit whoever relies on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A controlled experiment.&lt;/strong&gt; Send a small slice of real traffic through the new behavior and watch the metrics. Highest risk, highest cost. The guardrails are below.&lt;/p&gt;

&lt;p&gt;Evidence does not replace the decision. It is material for the person who signs. Write three stop lines, or evidence-gathering becomes a queue that never closes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop line one. Enough to classify. Stop.&lt;/strong&gt; Reliance has to name who uses this result to finish the next job. One of these is enough: reliance inside tickets, special handling downstream, or a shadow-run report that names the person and the job. With evidence of intent, the class is intentional compromise. With reliance and no evidence of intent, the class is a de facto commitment. "It happened," "someone reported it," and "downstream did not block it" are not enough. A pile of objections, with no fact of reliance, misses this line too. Complaints do not send the new system after the observation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop line two. The cheap paths are exhausted and still will not move. Stop.&lt;/strong&gt; Tickets, upstream and downstream, and the distribution have all been checked. No reliance you can point at. No evidence of intent. Nobody claims an accidental defect. High impact stays long-term open, and the module is not reported as equivalent. Medium and low impact are registered as known deviations. Do not default to the old behavior because the search stalled. That smuggles unsettled in as a promise. Do not write an accidental defect because you found no reliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop line three. Cost is over the cap. Stop.&lt;/strong&gt; Evidence-gathering has a budget: time, people, and traffic affected. Past the cap, stop. Mark it long-term open. Write the cap and the review date. The goal is whether anyone now relies on this result to get work done. The goal is not the historical truth. Do not spend without limit on a rare branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guardrails for a controlled experiment.&lt;/strong&gt; Who approves: the adjudicator and the technical lead, both. If either is missing, do not run it. The blast radius can be split. It can be rolled back. The metrics and the stop condition are written down. The traffic fraction is set in advance. If a metric crosses the threshold, roll back at once. Do not wait for the experiment window to end. Use this only for high-impact differences the other paths cannot close. It is not a routine tool.&lt;/p&gt;

&lt;p&gt;The rest of the duty stays. The difference list is signed. A signed remainder is an explicit risk. An unsigned one comes back, in a later iteration, as "nobody knows if this is right." Each record says who, when, on what basis, which class, and what was decided for that difference. The classes are intentional compromise, de facto commitment, accidental defect, and unsettled. If an accidental defect is kept, the record also says "inherited defect" and when the transition stops.&lt;/p&gt;

&lt;p&gt;What cannot be decided is registered as open, with a condition for review. Traffic past a stated volume. One evidence path returning a result. The budget cap reaching its review date. Do not leave it open with no date. A high-impact difference that is still unsettled means the module is not equivalent. If the open items are the bulk of the work, you do not have equivalence. You have a queue. If this role is empty from the start, the rewrite stops at observation. Do not finish the new code and then go looking for the person.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Confidence is three counts. The adjudicator's time goes in a queue.
&lt;/h2&gt;

&lt;p&gt;Confidence is computed from the hypothesis list in section 2. Report all three counts. Split the middle one. Provisional calls do not enter the three.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First count.&lt;/strong&gt; How many hypotheses observation confirmed. The hypothesis and the old behavior agree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second count.&lt;/strong&gt; How many are closed, and the result is not the original hypothesis. Split this. How many observation overturned: the path is live, and the real output disagrees with the guess in the structure. That behavior is closed. It still goes to section 4. It does not automatically follow the observation. How many are judged unreachable: dead branches, no entry, the basis written down, the noise removed, no business consequence. A basis that stops at "this call chain shows no entry" does not enter this half. Mark it provisional, on its own. Both halves are results. They are not still unknown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third count.&lt;/strong&gt; How many still have no input. Only inputs you have not built go here.&lt;/p&gt;

&lt;p&gt;Reporting only the first count is a coverage illusion. Adding the two halves of the second count into one number makes closed behavior look like residue. Folding provisional calls into unreachable reports an unconfirmed entry as closed. What is still open is the third count, plus the provisional list. The standard says what you compare by. The input space says where these hypotheses were hit. Confidence is these three counts, with the second count split, and the provisional list visible on its own.&lt;/p&gt;

&lt;p&gt;On a legacy system, human observation is often the only path that works. "Give it more time" must not become waiting. Four further constraints:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Directed construction.&lt;/strong&gt; Rare paths and error paths get inputs designed from the hypothesis list and from the data. More time spent rewatching the hot path does not raise coverage by itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A frozen baseline.&lt;/strong&gt; The longer you watch, the more the old system changes. The business changes. Dependencies get upgraded. Patches still land. Write down the time window, the version, and the batch of data. Later changes are registered as differences. The target does not move.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliver in stages.&lt;/strong&gt; Do not wait until observation is finished before you rewrite. For each module, hand over the three counts, the provisional list, and the classification of high-impact differences. Without a convergence people can see, the method holds on paper and runs out of patience inside the organization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freeze the cases.&lt;/strong&gt; Observation is not a spec. The record of input, output, and judgment is. Every observation enters the differential set. Without that, a longer watch only scatters.&lt;/p&gt;

&lt;p&gt;Cost sits on a separate sheet. Hours of human observation. Tools and people for static analysis. Upkeep of the differential environment. The adjudicator's time. The budget for evidence. The risk you will pay later for differences that remain. Without that sheet, you cannot say whether the process can continue. The adjudicator's time is usually the hardest line to schedule. When there is not enough of it, the queue below is the schedule. Another sentence of "look at the high-impact ones first" is not a schedule.&lt;/p&gt;

&lt;p&gt;Grade first. Then decide whether this hour includes a person.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High.&lt;/strong&gt; Money, an irreversible side effect, a promise the user can see, or many callers. The module is not equivalent until these differences are classified. The class may be intentional compromise, de facto commitment, accidental defect, or unsettled. Unsettled stays open, and section 4 starts, with the stop lines written down. An accidental defect needs an explicit claim. "We found no reliance" does not fill it in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Medium.&lt;/strong&gt; The behavior differs, the blast radius is one internal caller, or a mistake can be taken back. No separate meeting. The adjudicator reads one short list. Each line already has four things: the code hypothesis, the observed output, the proposed class, and who claims it, on what basis. One sitting, one batch. Incomplete claims stay off the list. A proposed de facto commitment names who uses the result to finish the next job. A ticket number alone is not complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Low.&lt;/strong&gt; Unreachable, or no output difference a caller can see. Register it as a known deviation. It does not take adjudicator time this round. If traffic hits it later, raise it to medium or high. Provisional calls do not enter this grade. An unconfirmed entry is not "no consequence."&lt;/p&gt;

&lt;p&gt;Incomplete evidence does not take the adjudicator's time. It goes back to observation or to evidence-gathering. What is still missing is the actual output, and who claims a compromise, a de facto commitment, or a defect. "The code looks like it" is not complete. "Someone reported it" is not complete.&lt;/p&gt;

&lt;p&gt;Fix a block of time each week. Cap the list. What does not fit stays in the queue. Staying in the queue does not become "follow the old behavior for now." That would collect a defect into a promise with no decision. If a high-impact item is still unclassified past this stage, this stage does not report the module as equivalent.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. One small module. The path only.
&lt;/h2&gt;

&lt;p&gt;This section is a sketch. It is not a manual. The module is fictional. One interface, four hypotheses, one signature. The traces that pair an input with an output are drawn as a few neat lines. The sketch makes the shape visible. On a real system, traces with no input are more common, and the evidence for a class is rarely as complete as "someone still remembers." Do not start work from this section. The classification rules, the stop lines, and the adjudicator queue are in sections 4 and 5. Those sections are the rules. They are still not a full operating manual.&lt;/p&gt;

&lt;p&gt;Sort the traces first. The gateway log has requests and responses: order id, cancel reason, status code. Those pair an input with an output. They can enter the differential cases. The order table has many rows marked cancelled, and no request from that time. Outcome only. Register a gap. Do not write a spec. A support ticket says cancel still succeeds after shipment. That is a hint, not a case. It tells observation to hit the input "already shipped." The ticket does not yet say whether this is reliance or an objection.&lt;/p&gt;

&lt;p&gt;Static analysis proposes four hypotheses, before any business explanation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Paid, and not shipped. Cancel returns success and writes the status to cancelled.&lt;/li&gt;
&lt;li&gt;Already shipped. Cancel returns a conflict. The status stays.&lt;/li&gt;
&lt;li&gt;An empty cancel reason still cancels successfully. The branch is in the code. The comment looks added later.&lt;/li&gt;
&lt;li&gt;An internal flag skips every check. No entry is visible on the call chain.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Observation hits them. Hypothesis 1: the input matches, the output matches, confirmed. Hypothesis 2 is overturned. A shipped order still returns success, and the status becomes cancelled. The path is live. The real output disagrees with the hypothesis in the code. Stop here. Do not announce that the new system follows the observation. Hypothesis 3: the logs contain no request with an empty reason, and this round built no input for it. Not hit yet. Hypothesis 4: the static call chain of this version shows no entry. Reflection and external triggers are unchecked. Provisional, listed on its own, pending review. Not written down as confirmed absent. Not placed among the closed.&lt;/p&gt;

&lt;p&gt;The three counts. Confirmed: 1, cancel succeeds before shipment. Closed, and not the original hypothesis: 1, the overturn. Cancel still succeeds after shipment. Unreachable this round: 0. Not hit yet: 1, the empty cancel reason. Hypothesis 4 is provisional, on its own, outside the three counts. Still open: the one not hit, plus this one provisional call. Only the overturned hypothesis enters classification.&lt;/p&gt;

&lt;p&gt;The equivalence standard was written in advance. This interface needs matching output and matching side effects: the order status, and the cancel message that goes out. Timing is out of scope this round. The overturned line is high. A user can see it, and it changes an order.&lt;/p&gt;

&lt;p&gt;Take the branch where someone remembers. An old operator remembers. Years ago the warehouse interface was unreliable. They left "cancel still allowed after shipment" on purpose, so a person could file a manual replacement. Support can show that people still use it, and that the use is the replacement order. That is an intentional compromise. The basis is the old constraint and the current use. The basis is not "the code does this," and not "a ticket mentioned it." The product owner signs. The class is intentional compromise. What is kept is a promise. The new system follows the observed output. It does not follow the hypothesis in the code that this should return a conflict.&lt;/p&gt;

&lt;p&gt;Then take the branch where nobody can say why. Gather evidence as in section 4.&lt;/p&gt;

&lt;p&gt;Tickets. Of 14 tickets in the past year, 11 are support using "cancel still works after shipment" to file a manual replacement. The user is waiting on a refund or a reroute. Someone uses this result to finish the next job. The other 3 are users objecting: the goods already shipped, so how can cancel still succeed. Those are objections. They do not support a de facto commitment.&lt;/p&gt;

&lt;p&gt;Upstream and downstream. Callers do no special handling of this status. The warehouse only recognizes cancelled. It does not distinguish before and after shipment. That only means downstream did not block the path. It is not a contract. The reliance does not come from here.&lt;/p&gt;

&lt;p&gt;Distribution. This path is about 3% of cancels, clustered in promotion season. The volume says the cheap paths are worth finishing. It does not classify by itself.&lt;/p&gt;

&lt;p&gt;The three cheap paths are done. There is reliance, from those 11 replacement orders. There is no evidence of intent. Stop on line one. The class is a de facto commitment. The signature keeps existing reliance. The record says: no evidence of intent. The reliance is support using cancel-after-shipment to file a replacement, not the 3 objections. A change has to notify support, and the users who finish a refund or a reroute through that replacement. Do not write intentional compromise. Do not write accidental defect. The 3 objections only say that some people do not want this result. Nobody has claimed that this was a mistake and that nobody uses it to get work done.&lt;/p&gt;

&lt;p&gt;If all 14 tickets had been objections, stop line one would fail. A report alone is not a de facto commitment, and it does not send the new system after the observation.&lt;/p&gt;

&lt;p&gt;If the three paths end with no reliance you can point at, and nobody claims an accidental defect, stop on line two. High impact stays long-term open. The module is not reported as equivalent. Medium and low impact become known deviations. Do not default to the old behavior.&lt;/p&gt;

&lt;p&gt;Hypothesis 4 stays provisional. It does not enter this adjudication, and it does not enter the low grade of known deviations. The note says: no entry on the current call chain; reflection and external triggers not checked; confirm at runtime. Hypothesis 3 has not been hit, so it is not classified. The high-impact line is already signed as a de facto commitment, so this module can enter differential testing. Hypothesis 3 is not absent. Hypothesis 4 is not unreachable. This sketch is not a procedure other modules can copy.&lt;/p&gt;

&lt;p&gt;What this round hands over is not new code. It is a frozen baseline, cases that have inputs, three counts split open, one provisional call on its own, and one signature that names the class.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Quality control on the new code is not equivalence with the old system.
&lt;/h2&gt;

&lt;p&gt;Some teams string red lines, mutation tests, human review, and a final acceptance check into one quality gate. The problem is real. Generated code cheats. Coverage gets inflated. A local edit does not converge. A team writing code with a model can use those constraints directly.&lt;/p&gt;

&lt;p&gt;What that gate checks is whether the new code stands up, with a person at the end. The spec is mostly someone reading the old code and generating a document. That is a sample. The gate checks the new code's own tests. It does not check the old system and the new one on the same input. There is no paired run, no three counts, no classification after an overturn, and no stop lines for when you cannot tell.&lt;/p&gt;

&lt;p&gt;A small team with a strong reason, treating the old project as the requirements document, can run that gate. It cannot answer why the rebuild should be called complete. As a quality constraint inside one effort, the description is fair. As the whole method of a rewrite, it sits in the wrong place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Close
&lt;/h2&gt;

&lt;p&gt;Seven things turn a rewrite into a process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inventory the traces.&lt;/strong&gt; Only an input paired with an output becomes a case. An outcome alone is a gap. If the traces as a whole are too thin, do not replace the whole system. Run the same loop on a surface that real traffic can hit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static analysis produces hypotheses. Observation confirms or kills them.&lt;/strong&gt; What you cannot hit is a risk. The number of extracted branches is not the coverage denominator. An overturned hypothesis is a closed disagreement. It is not yet a decision about which side the new system follows. Unreachable needs a written basis. A thin basis is provisional. List it on its own. Keep it out of the closed count. Do not write it down as absent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write the equivalence standard per module.&lt;/strong&gt; Output and side effects default to recovering the old behavior. For timing and error behavior, decide the allowed gap first, then compare. Rank conflicts in advance. The comparison is between the old system and the new one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The business decision classifies first.&lt;/strong&gt; Intentional compromise enters through evidence of intent. A signature to keep it keeps a promise. A de facto commitment enters through reliance you can point at. Evidence of intent may be missing. The record names the job. An accidental defect enters through an explicit claim that it was a mistake, and that nobody uses it to get work done, or that using it causes harm. To keep one, write "inherited defect" and the date the transition stops. Finding no reliance does not fill this class. Unsettled stays open. Live behavior, or a report that it happened, does not promote it into a promise. When the person who understands and the person who can sign are different, the first explains and the second signs. The person writing the code holds neither seat. A high-impact item that is still unsettled means the module is not equivalent. An empty role means you stop at observation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it is unsettled, gather evidence, and write three stop lines.&lt;/strong&gt; Enough to classify: stop. Enough means you can name who uses this result to finish the next job, or you have evidence of intent. Cheap paths exhausted: stop. Over the cost cap: stop. Split tickets into reliance and objection. A downstream system with no special handling is not a contract. The question is whether anyone now relies on this result to get work done. The question is not what the original author meant. A controlled experiment needs both signatures, a way back, and a stop condition. Use it only when the impact is high and the other paths are stuck. If you cannot close it and the impact is high, leave it open for the long term. Do not report the module as equivalent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The adjudicator's time enters a queue by grade.&lt;/strong&gt; High and still unclassified: this stage does not report the module as equivalent. Medium: one short list, read in one sitting. A proposed de facto commitment names who uses the result to finish the next job. Incomplete evidence does not consume this time. Low: register only. Provisional calls stay out of the low grade. What does not fit the cap stays in the queue. It does not default to the old behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Report confidence as three counts.&lt;/strong&gt; How many confirmed. Inside what is already closed, how many were overturned by observation, and how many are unreachable on a written basis. Both of those are results. How many no input has hit. Provisional calls stay on their own list. They are not folded into unreachable. What is still open is the not-yet-hit count, plus the provisional list. Freeze the baseline. Deliver in stages. Freeze the cases.&lt;/p&gt;

&lt;p&gt;With all seven, "rebuilt completely" stops being a sentence nobody can judge. It becomes a process you can measure, decide, and stop. Drop one piece, and the work falls back to this: the new code passed its own tests, so it is done. The example only shows the shape. It does not stand in for the classification, the stop lines, or the adjudicator's queue.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>agents</category>
    </item>
    <item>
      <title>A Triple Is Not a Trace</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Tue, 20 Oct 2026 10:37:45 +0000</pubDate>
      <link>https://dev.to/zxpmail/a-triple-is-not-a-trace-pnl</link>
      <guid>https://dev.to/zxpmail/a-triple-is-not-a-trace-pnl</guid>
      <description>&lt;h1&gt;
  
  
  A Triple Is Not a Trace
&lt;/h1&gt;

&lt;p&gt;Two camps keep missing each other. One treats an event as a real modeling object: you do not rewrite it, a process still in progress is not the finished event, and a status field is only a projection. The other looks at the stack those words usually drag in. OWL is expensive to run, SPARQL is a poor daily tool, and a triple store is a narrow piece of infrastructure. What a team can actually keep is the model in the code.&lt;/p&gt;

&lt;p&gt;Both are pointing at the same gap. A triple is the smallest thing you can store. It is not yet something you can trace.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(AS-12, overheated, 2026-10-20)&lt;/code&gt; is an assertion. You can store a hundred more in the same shape and still have a pile. Three questions turn the pile into a trace.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is this edge legal?&lt;/strong&gt; What may connect to what, and which way does the arrow point?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When does a legal edge count?&lt;/strong&gt; The moment the event happened and the moment the edge was written are different clocks. "What was in the set at time T" uses the write. The system stamps that write. The caller does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which list is in force?&lt;/strong&gt; A new kind of part, or a second work order, is a version choice. It is not a quiet extra edge.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Skip any one of these and you can still store triples. What you lose is the ability to run the same trace twice and get the same answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  One work order, three cuts
&lt;/h2&gt;

&lt;p&gt;Device AS-12 overheats. Someone files a repair, a job is dispatched, a technician does the work, the order is closed. The bare triple becomes an event, OV-1, not a word painted on the device. OV-1 brings a situation, "awaiting a report." The rest of the chain follows: report, dispatch, repair, close. The work order and the technician are objects that stay. The overheating and the repair are things that happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A device is not a part of the repair.&lt;/strong&gt; That edge is illegal. If you allow &lt;code&gt;AS-12 part-of FIX-9&lt;/code&gt;, the question "what is this repair made of?" returns a machine. The legal parts, if you care about them, are the steps: diagnose, replace, retest. They hang on the repair event. They are not parts of each other, and the device enters the story by taking part in the event, not by being a piece of it. This check belongs in the first tier. It is a rule in the write path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A wrong record does not rewrite the repair.&lt;/strong&gt; Suppose the original record left out the retest. You do not open FIX-9 and edit it. You append a correction that argues with that one fact. The repair event stays the same individual. Later corrections argue with the same fact; the later one, when neither record is the parent of the other, wins. Before you compare them, drop every correction that had not been written yet. If you compare first and drop second, a correction from the future changes the winner, and deleting it afterward does not put the old winner back. This is the second tier. You do not need it until a stored fact can be wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A mistaken close is a new event, not a deleted one.&lt;/strong&gt; CL-1 happened. Leaving it in place is the point. Undo it with another event, &lt;code&gt;UNCL-1 → CL-1&lt;/code&gt;, and a new situation node whose type is "awaiting acceptance" again. Do not reuse the old node. If a further event &lt;code&gt;UNCL-2 → UNCL-1&lt;/code&gt; brings a new node of type "closed," the close is in effect again, and both compensation links are still there. CL-1's direct compensation is still UNCL-1, not UNCL-2. The current stage is whatever that latest node says. This is the full tier. Build it when undoing a business effect matters. Do not build it so you can reject &lt;code&gt;AS-12 part-of FIX-9&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A second work order can share the dispatch and still have its own stage. The small tier does not answer that. The second tier does, by keeping each order's situation chain separate. The status column on the work order may still say "in progress" after the chain says "closed." The column is a projection. When they disagree, the chain is the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three tiers, because the full stack is how you reinvent OWL
&lt;/h2&gt;

&lt;p&gt;The engineering objection is fair. If every team has to keep kind catalogs, correction locks, two clocks, and a closed query language, the maintenance bill can exceed the stack this was supposed to replace. One ordering rule — drop late records, then compare — is already easy to write backwards. So the full procedure is not the entry price.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;What you maintain&lt;/th&gt;
&lt;th&gt;What you can answer&lt;/th&gt;
&lt;th&gt;What you do not claim&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;td&gt;Endpoint checks. Nothing is a part of itself. Events are appended, not edited. One work order. Count events of a type directly.&lt;/td&gt;
&lt;td&gt;What happened on this order. How many times it overheated.&lt;/td&gt;
&lt;td&gt;A corrected parts list. A second order's stage.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Second&lt;/td&gt;
&lt;td&gt;Corrections that name the fact they dispute. Drop records that were not written yet, then pick the winner. A second order gets its own chain.&lt;/td&gt;
&lt;td&gt;Whether the retest is part of the repair after the correction. Each order's current stage.&lt;/td&gt;
&lt;td&gt;Compensation. Counts that include subtypes. A catalog of part kinds.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Part kinds, with a default rule instead of a handwritten pair list. Compensation as its own link. A closed set of query shapes, so the next question cannot invent a new query language.&lt;/td&gt;
&lt;td&gt;A close that was undone, without deleting the close.&lt;/td&gt;
&lt;td&gt;That you needed this tier for the rows above.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Path existence stays proportional to the number of edges at every tier. Listing every path is the expensive query. The table above is the cost of keeping the rules, which is the cost that matters.&lt;/p&gt;

&lt;p&gt;The small tier fits in one module two people can read. There is no reasoner. The second tier adds one piece of code and a test that the order of operations is the right one. The full tier costs review, whenever a new part kind or a new query shape is allowed in. It does not cost a reasoner on every read.&lt;/p&gt;

&lt;p&gt;Stop at the tier that answers the question you have. A standards body can adopt the second tier and leave the rest. That is a smaller decision than swallowing a whole ontology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this sits
&lt;/h2&gt;

&lt;p&gt;OCEL already gives you objects, events, and participation. PROV already points a record at the record it came from. EPCIS dispositions are close to the type of a situation, and they are not the node on the chain. Event sourcing already refuses to rewrite what was stored. It usually still uses one kind of appended message for both "the record was wrong" and "the business effect must be undone." Those are different messages. The split is the whole integration.&lt;/p&gt;

&lt;p&gt;SNOMED CT, FHIR, FIBO, OPC UA, EPCIS: each one grew up to carry a slice, under real pressure to interoperate. None of them is a single picture of objects, events, situations, and participation. This is the same shape. The three questions are a check an implementation can adopt beside those interfaces. They do not replace the interfaces.&lt;/p&gt;

&lt;p&gt;A trace is not a denser pile of triples. It is the same pile after the three questions have answers, at a tier the team will still be maintaining next year. The checklist, the lock, and the test that fails if you compare corrections before you drop late records are version 1 of the decision procedure: &lt;a href="https://github.com/zxpmail/blog/blob/main/articles/decision-procedure-v1.md" rel="noopener noreferrer"&gt;articles/decision-procedure-v1.md&lt;/a&gt;. They do not belong in this post.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>ontology</category>
      <category>software</category>
    </item>
    <item>
      <title>Between the Company Brain and the Execution Layer, a Task Ledger Is Missing</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Thu, 15 Oct 2026 09:40:30 +0000</pubDate>
      <link>https://dev.to/zxpmail/between-the-company-brain-and-the-execution-layer-a-task-ledger-is-missing-4f46</link>
      <guid>https://dev.to/zxpmail/between-the-company-brain-and-the-execution-layer-a-task-ledger-is-missing-4f46</guid>
      <description>&lt;h1&gt;
  
  
  Between the Company Brain and the Execution Layer, a Task Ledger Is Missing
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;2026-10-15&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a company, sales has explained which objection kills a deal. Marketing has corrected an outdated claim. Operations has told an agent which numbers can be trusted. Most of those corrections stay in private chats, personal settings, and separate tools. The next person cannot use them.&lt;/p&gt;

&lt;p&gt;An agent at execution time is a different failure. It calls a tool, gets real feedback, and an unverified assumption stays in the dialogue. Later reasoning keeps following it. Gaoling School of Artificial Intelligence at Renmin University calls this task-state contamination: unverified assumptions, outdated plans, and wrong progress judgments remain in the interaction history and steer later action. The paper is &lt;a href="https://arxiv.org/abs/2609.28416" rel="noopener noreferrer"&gt;Agent-Editing World Model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The two look alike. One is something learned that never entered a shared place. It was not recorded. The other is a judgment that should not have stayed in the history. It was not removed. They are not one disease. They also do not weld into an automatic loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The company brain: a judgment that still holds has to be usable by the next person
&lt;/h2&gt;

&lt;p&gt;A company brain is not a knowledge base, and it is not a stack of directories. Directories are only where things sit. What has to remain is the loop. Work happens. Someone corrects it. The correction is routed. Someone reviews it. It is written into a shared place. The next piece of work can use it.&lt;/p&gt;

&lt;p&gt;Review needs three roles. The process owner watches whether this process is still running. The domain reviewer checks whether the correction is right for the business, and owns the ledger for this task. The final decider settles it when two sources conflict. In a small team, the process owner and the domain reviewer can be the same person. The decider cannot be the author of this correction. Who may change it, and who deletes it when it goes stale, is named the same day. If a role is empty, the weekly maintenance does not happen. The directories get built, then no one maintains them, and no step of the work has to read them.&lt;/p&gt;

&lt;p&gt;What it answers is a standing rule, not whether this one step should be taken.&lt;/p&gt;

&lt;p&gt;What the company believes now. Which decisions replaced older ones. Who has the final say. How this kind of work should be done.&lt;/p&gt;

&lt;p&gt;Four things are enough. Memory: the facts, decisions, and history that matter now. Rules: what counts as good work, and what must not be done. Capability: skills and workers that can be run again. Learning: reviewed corrections, used to change the first three.&lt;/p&gt;

&lt;p&gt;Do not call the rules a judgment yet. The execution layer has another kind of call: whether this single step moves the task forward. Use one word for both, and the three layers collapse into one.&lt;/p&gt;

&lt;p&gt;The smallest set of files can be these: &lt;code&gt;company-brief.md&lt;/code&gt;, &lt;code&gt;priorities.md&lt;/code&gt;, &lt;code&gt;decisions/&lt;/code&gt;, &lt;code&gt;people/&lt;/code&gt;, &lt;code&gt;projects/&lt;/code&gt;, &lt;code&gt;policies/&lt;/code&gt;, &lt;code&gt;skills/&lt;/code&gt;, &lt;code&gt;workers/&lt;/code&gt;, &lt;code&gt;learnings.md&lt;/code&gt;. Before an agent starts, it reads a company map. What we do. What matters most now. Which source wins. Where to look up decisions, policies, skills, and workers.&lt;/p&gt;

&lt;p&gt;This layer can be done today. It does not wait for AEWM.&lt;/p&gt;

&lt;h2&gt;
  
  
  AEWM: borrow the call, do not plug in the model
&lt;/h2&gt;

&lt;p&gt;AEWM turns the question. It does not predict what the tool will return. It looks at what this step does to progress on the task.&lt;/p&gt;

&lt;p&gt;It has two abilities. Action Judge sorts the step into three kinds: critical progress, useful exploration, and useless repetition. The paper's words are Critical, Exploratory, and Noisy. State Revision: if the step is useless repetition, rewrite the reasoning and the next action from the same history that has already happened.&lt;/p&gt;

&lt;p&gt;EditAct puts that into execution. The agent proposes a step. AEWM calls it. Keep it or rewrite it. Then actually run it, and write the result into the history. The rewrite has to enter the next step. A note that says "think again" does not count.&lt;/p&gt;

&lt;p&gt;One terminal case in the paper: the agent checked an IPv4 port, did not find the target, and treated the service as not listening. AEWM noticed the code bound IPv6, changed the next step to check IPv6, and the port was listening. The task later passed its tests.&lt;/p&gt;

&lt;p&gt;Read the numbers in the paper's terms. On their Action Judge benchmark, macro-F1 is 70.5%, 10.6 points above the strongest comparison. That number is how often a prediction made before execution agrees with a label written after the whole trajectory was seen. It is not "70% of enterprise tasks succeed."&lt;/p&gt;

&lt;p&gt;Task success is a different number. On Terminal-Bench 2.0, Qwen3.5-35B-A3B with the previous method scores 37.1%. With EditAct it scores 48.3%. That is one model and one terminal benchmark. AEWM-RFT also shows that revised trajectories can be written into the agent's own ability. After that, AEWM is not called. The agent still beats one trained only on its own successful trajectories, by 2.2, 2.6, and 2.5 points.&lt;/p&gt;

&lt;p&gt;These are results inside the paper's setup. An enterprise workflow cannot copy them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The missing piece is a task ledger
&lt;/h2&gt;

&lt;p&gt;Glue the company brain and AEWM into an automatic loop, and this layer is what you skip.&lt;/p&gt;

&lt;p&gt;The organization layer is the company brain. It holds relatively stable facts, decisions, policies, skills, and workers. It answers what the company believes now.&lt;/p&gt;

&lt;p&gt;The task layer is a ledger. One sheet per task. Six lines at minimum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task ledger
Verified facts: (source; who confirmed)
Unverified assumptions:
Excluded branches:
Unmet requirements:
Current progress:
Next question to check:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A verified fact names its source, and who confirmed it. Anything unconfirmed stays under unverified assumptions. Moving a line from assumption to verified takes a nod from the domain reviewer. A ledger with no owner is still a private chat for this task.&lt;/p&gt;

&lt;p&gt;Without the ledger, a stale rule in the company brain flows into this task. AEWM also judges the step from an incomplete history. If someone maintains the ledger, many questions of "does this step help" can be read off the sheet first. A model is not required first.&lt;/p&gt;

&lt;p&gt;The execution layer is not the model layer. Start with rules, checklists, and prompts. Is this step critical progress, useful exploration, or useless repetition. If it is useless repetition, what reasoning and action replace it. The replacement has to be executed for real. Collect trajectories and measures, then talk about a model.&lt;/p&gt;

&lt;p&gt;After execution, route through the company brain's loop. A missing fact goes to company knowledge. A new strategic choice goes to the decision record. A repeated preference goes to policy. A trick that worked goes to skills. A sequence that can be run again goes to workers. These are reviewed before they are written back. They are not written into the company brain automatically.&lt;/p&gt;

&lt;p&gt;A gate and a review are not the same thing. The gate covers irreversible actions, and it blocks them before execution. Review covers what may be written back into shared knowledge, and that can wait. If a dangerous action only sits in the weekly review queue, the gate is just another folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small first, then a checklist, then a model
&lt;/h2&gt;

&lt;p&gt;Stage one is the smallest company brain. Pick one process that keeps coming back. Build the smallest directory. Give the agent a company map. Name the three roles. People may overlap. The decider cannot be the author of this correction. Run the correction route and the weekly maintenance. If a role is empty, stop here. Do not go on.&lt;/p&gt;

&lt;p&gt;Stage two adds the task ledger and a checklist. Use the six lines above. A verified fact with no source and no confirmer still counts as an unverified assumption. Review by hand with "critical progress / useful exploration / useless repetition." Try it on real tasks.&lt;/p&gt;

&lt;p&gt;Stage three triggers a rewrite on useless repetition. Collect trajectories that real feedback has checked. See whether rework and useless loops go down. See whether useful exploration was killed by mistake.&lt;/p&gt;

&lt;p&gt;Stage four is when a model can be considered. Enough trajectories of clear quality. Stable review. Explicit measures. Then consider training of the AEWM kind, or fine-tuning on revised trajectories. Do not start with an automatic loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the account
&lt;/h2&gt;

&lt;p&gt;When sources conflict, the final decider settles it. The author of this correction cannot also be the decider for it. Someone deletes knowledge when it goes stale. When it is wrong, it is clear whose it is.&lt;/p&gt;

&lt;p&gt;If AEWM is actually called on every step, the call and the rewrite add delay and cost. A wrong call can kill useful exploration. Maintaining the company brain is ongoing human work.&lt;/p&gt;

&lt;p&gt;Look at these, not at whether the directories exist. Rework rate. How often stale information is treated as a current fact. Time spent on review. Task success rate. Whether useless repetition went down. Whether useful exploration stayed.&lt;/p&gt;

&lt;p&gt;A person who has tuned an agent well holds a private advantage. Asking them to hand the correction over requires recognition. Otherwise the company brain gets no input.&lt;/p&gt;

&lt;p&gt;The company brain lets a rule that still holds be used by the next person. The execution layer looks at the step before it runs: progress, exploration, or repetition of an assumption that no longer holds. The execution layer starts as a checklist, not a model.&lt;/p&gt;

&lt;p&gt;Between them is a six-line task ledger. What is verified has a source and a confirmer. Writing back to shared knowledge goes through review, and the decider is not the author of that correction. Irreversible actions are blocked by the gate before they run.&lt;/p&gt;

&lt;p&gt;The company brain can be done today. Treat AEWM first as a checklist and a design principle, not as a model you plug in. When the trajectories, the review, and the measures are in place, then talk about a model.&lt;/p&gt;

&lt;p&gt;A correction has to be reviewed, written down, and usable next time before later steps get better. If the decider is the author of the correction, one lesson still stays in that one conversation.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>agents</category>
    </item>
    <item>
      <title>The Definition Is the Kernel. What Still Runs After the People and the Model Change Is the Asset.</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Tue, 13 Oct 2026 10:37:12 +0000</pubDate>
      <link>https://dev.to/zxpmail/the-definition-is-the-kernel-what-still-runs-after-the-people-and-the-model-change-is-the-asset-4jcm</link>
      <guid>https://dev.to/zxpmail/the-definition-is-the-kernel-what-still-runs-after-the-people-and-the-model-change-is-the-asset-4jcm</guid>
      <description>&lt;h1&gt;
  
  
  The Definition Is the Kernel. What Still Runs After the People and the Model Change Is the Asset.
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;2026-10-11&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A while ago I read a piece from Tencent's engineering team. The real change, it argued, is not AI coding alone. It is the whole development process. Their OK platform delivers requirements end to end with AI. Automation is 68%. 51% of requirements finish within two hours.&lt;/p&gt;

&lt;p&gt;The numbers are bright. They show that requirements can be finished fast. They do not answer a second question. In this way of working, what stays with the organization, and what leaves with the people and the model.&lt;/p&gt;

&lt;p&gt;I spent an afternoon on that question with my boss. His judgments sit closer to this layer than that piece does. What follows is only the part that survives one test.&lt;/p&gt;

&lt;p&gt;Change the people. Change the model. Change the vendor. Can the system still run at a similar quality and speed?&lt;/p&gt;

&lt;p&gt;If it can, it belongs to the organization. If it cannot, it is one person's feel, one generation of model, or a lock-in to one vendor. "Quality" in that sentence cannot be graded by the system itself. The outside measure is in section 7.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. A problem with no boundary is a wish
&lt;/h2&gt;

&lt;p&gt;My boss opened with two lines. What problem are you solving. Who is it for.&lt;/p&gt;

&lt;p&gt;Most teams landing AI stop one step earlier. "I want to study what software an industry needs." "I want to build a general agent platform." Those are wishes. A wish has nowhere to stop, and no way to be checked.&lt;/p&gt;

&lt;p&gt;His split has three steps. What the problem itself is. Who is looking, and from which angle. Where the boundary is: the domain.&lt;/p&gt;

&lt;p&gt;"Study industry software" became three problems, each able to stop. In the agent era, what software does an industry actually need. That is the demand baseline. What can current open-source projects provide. Are they stable. Can they be integrated. How large is the gap. That is the supply side. How software of any kind becomes components. That is the technical method.&lt;/p&gt;

&lt;p&gt;Once they are separated, each one has a place to converge.&lt;/p&gt;

&lt;p&gt;A definition decides what to do, and what counts as right. A definition written on a wiki and executed by no one is a liability. A definition welded to one set of tools, gone when the tools are swapped, is not yet an asset. The kernel is the layer that is still there after the carrier changes, and that can still constrain the next run. The toolchain and the runtime are the carrier. How that layer is drawn is in section 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. There has to be structure. Structure inside the prompt cannot stop what already happened.
&lt;/h2&gt;

&lt;p&gt;One line from him stayed with me. There is nothing wrong with form. Without form, the content has nothing to sit on. Without a body, what soul is there to talk about.&lt;/p&gt;

&lt;p&gt;He did not mean more stamps on a document. He meant the content needs a structure to hold it.&lt;/p&gt;

&lt;p&gt;Most prompts are one linear sentence. "Help me look up what software this industry has." The model can only guess. He asks for these, written apart: goal, context, conditions and constraints, output format, the agreements that matter, where to inject, which passage to cite. Goals can have sub-goals. Context loads as needed. Constraints go in by layer. Checkpoints in the flow are marked on their own, not mixed into the same sentence.&lt;/p&gt;

&lt;p&gt;A prompt should be folded, injectable, and full of variables. The way a loop or a queue is organized in code is the way a prompt should fold. Longer is not better. Less redundancy and clearer folding work better.&lt;/p&gt;

&lt;p&gt;This only says one thing. One linear sentence carries too little. It has not yet met the harder failure.&lt;/p&gt;

&lt;p&gt;You write in the prompt, "if it does not pass, clarify." The model has already produced an answer. It treats the step as done, and goes on. Your sentence never gets a chance to run.&lt;/p&gt;

&lt;p&gt;Structure is still necessary. Structure written inside the prompt is soft. For the flow to be able to stop, the check has to sit outside the model. A primitive in the runtime. A forced checkpoint in a script, before execution and after. No pass, no next stage. Whatever is not exposed can be bypassed. This is the same thing as design by contract. Preconditions, postconditions, and invariants are part of the system. They are not a reminder in a document.&lt;/p&gt;

&lt;p&gt;If these checks live only inside one product, the set disappears when the vendor changes. What has to stay is what the check looks for. Where the check is built does not have to stay.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The same rule, put in two places, has two results
&lt;/h2&gt;

&lt;p&gt;He had another abstraction. High-dimensional data can be used as a program. A program is itself data. Dictionaries, knowledge bases, specs, and rules look like data. When the structure is good enough, they drive the flow. A program can also be injected, folded, and combined. Write fewer fixed steps. Write the rules that generate the steps.&lt;/p&gt;

&lt;p&gt;That sentence needs a minimal scene, or it stays a label. The scene takes only one kind of rule. If it is missing, there is no next step.&lt;/p&gt;

&lt;p&gt;A cross-domain request needs five dimensions. The other side gave two.&lt;/p&gt;

&lt;p&gt;Put "stop if the dimensions are incomplete" into the prompt. The model fills in the form, treats the step as handled, and continues.&lt;/p&gt;

&lt;p&gt;Write the same rule as a record the runtime must read before submit. Five fields. Three missing. This step does not open.&lt;/p&gt;

&lt;p&gt;The first hopes the model will obey. The second says the condition does not hold, so the next step does not exist in the flow. For a dictionary or a spec to act as a program, something outside the model has to read it. The model can be the machine that generates the content. The gate does not read a wish in the prompt. The gate reads the record.&lt;/p&gt;

&lt;p&gt;He also made another comparison. Three of the five dimensions are themselves vague. There is no unique answer. Another person could not produce one either. That is a different failure. It belongs in section 6. The gate does not handle it.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The ontology describes the world. The gate checks this time.
&lt;/h2&gt;

&lt;p&gt;The request in the last section was about the gate. It did not yet say how the gate relates to the ontology. One sentence here. The ontology describes what this world contains. The gate checks whether this time is allowed. A specification can say "confirm shipment." That does not mean this shipment may go. The gate has to stand independent of the ontology.&lt;/p&gt;

&lt;p&gt;At the end of the conversation he reduced things to four words. Things, relations, actions, plus context. Entity, relation, action, context.&lt;/p&gt;

&lt;p&gt;The split below is one I added while organizing this. He had not already separated it.&lt;/p&gt;

&lt;p&gt;An action inside the ontology is a business verb. Check inventory. Confirm shipment. It describes what can happen in this world. A relation describes what connects to what. Context is the scene this time. Written down, this is a specification. It makes it possible for a person or a model to get it right.&lt;/p&gt;

&lt;p&gt;An action on the gate is whether this time is allowed. Are the fields complete. Does it pass to the next stage. This layer is not written into the specification in the hope that it will be obeyed. It is a check at execution time.&lt;/p&gt;

&lt;p&gt;He also split evolution into three levels. What a spec looks like in each domain is the top level. The concrete content under that shape is the middle level. A particular instance is the bottom level. Higher is more general. Lower is more specific.&lt;/p&gt;

&lt;p&gt;The kernel takes only the layer that can still constrain the next run after the carrier changes. The shape of the spec belongs to this layer. It decides which slots exist, and what counts as right. Content in the slots counts only while someone keeps it true. If no one maintains it, the kernel is only the shape. Expired content can be carried across intact. The next run is no longer constrained by it.&lt;/p&gt;

&lt;p&gt;What the check looks for is "what counts as right," taken and executed. The shape is how the problem's boundary, and that sentence "what counts as right," get written down. When the two sides match, it is still this one layer. When what the check looks for does not match "what counts as right," that is a fault. It is not an extra layer.&lt;/p&gt;

&lt;p&gt;Which product this check is built into is the carrier. What leaves when the model changes is the instance inside one prompt, and the gate inside one vendor's product.&lt;/p&gt;

&lt;p&gt;A general method, plus the entities of a domain, is what can land in that domain. That does not mean every industry must invent its own method. An empty template does not automatically become an industry conclusion. He later turned to manufacturing first. That is a decision. The meta-method lands in manufacturing first. It does not spread across every industry first.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Mistakes will happen. The cage decides whether you dare to use it.
&lt;/h2&gt;

&lt;p&gt;One practical line from him. An agent cannot avoid mistakes. What matters is how a company dares to use an agent that will make them.&lt;/p&gt;

&lt;p&gt;Give it a cage. A gate at the entrance. A check at the exit. Rollback when it is wrong. A person at the decisions that matter. When it reaches past its authority, a person decides whether to grant it.&lt;/p&gt;

&lt;p&gt;The prior check sits in the cage too. Three of five fields are missing. That step should not start. Checking whether the input is valid is required. It is not something you look at after the run.&lt;/p&gt;

&lt;p&gt;This check can stop a missing field. It cannot stop the case in the next section. The slots are full, and the problem still has no unique answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Two things are still unsolved
&lt;/h2&gt;

&lt;p&gt;The direction is right. The conversation already showed two hard limits.&lt;/p&gt;

&lt;p&gt;The first is how formalization continues. Structure, dictionaries, knowledge bases, specs. Who writes them. Who changes them. Who updates them before they expire. Too coarse, and they do nothing. Too fine, and they freeze. In the conversation this showed up as "it cannot be written," "it is too fragmented," "it is not normalized." That is not a team that failed to try. Formalization is expensive. Tools can lower the cost. People still find it troublesome. They call it formalism. When a person leaves, knowledge that was never written into the system breaks. That is a further layer. Why would an organization keep writing things down as structure. Tools do not lower willingness. The system can already be cheap, and people still will not use it. If no one maintains it, the kernel is only the shape.&lt;/p&gt;

&lt;p&gt;The second is how you find out the structure itself is wrong. Back to that request. If the five dimensions are simply unfilled, the gate can close. The other half of what he said: three of them are themselves vague, and there is no unique answer. All five slots contain words. The gate lets the request through. Another person still cannot produce a unique answer. The gate can stop a missing field. It cannot stop "these five dimensions were the wrong five." It cannot stop a knowledge base running along a wrong map. Wrong content, kept as if it were true, still counts by the kernel's own ruler. So "the quality is still there" cannot be graded by the kernel.&lt;/p&gt;

&lt;p&gt;A model that cannot read a structure that is too complex, or that gets worse when the context is too long, is today's floor on ability. This method cannot run in every setting yet. That floor is not a permanent boundary of the method.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. What you can take with you
&lt;/h2&gt;

&lt;p&gt;Models will be replaced. They will become ordinary goods. They will be open-sourced. Prompt technique will lose its price quickly. Rules that only sit on a wiki are a liability. Rules welded into one toolchain, or one product, disappear when the carrier changes. Those are not assets either.&lt;/p&gt;

&lt;p&gt;What you can take with you is that layer. It is still there after the carrier changes, and it can still constrain the next run. The toolchain, the runtime, and which product the gate is built into, are the carrier.&lt;/p&gt;

&lt;p&gt;Whether the quality is still there has to be read from results the kernel cannot alter. Can the thing that was handed over be used. Can the person receiving it actually take it. When it is wrong, can someone outside see it. A wrong kernel can move intact onto the next carrier and, by its own ruler, feel that it still runs well. That is still not an asset.&lt;/p&gt;

&lt;p&gt;Apply the same test to the OK platform. 68% automation, and 51% of requirements finished within two hours, answer "fast." Fast is an outside number. It measures throughput. It does not answer whether, after a new model, a new group of people, and a new vendor, someone outside can still see a similar quality. That number is not there yet. Until it is, the piece shows throughput. It does not show an asset.&lt;/p&gt;

&lt;p&gt;This is organized from an internal conversation. The judgments are my boss's. In section 4, the relation between the ontology and the gate, and the split of action into two layers, are additions I made while organizing. Collapsing the kernel into "the layer that can still constrain the next run," counting content only while someone keeps it true, and reading quality from outside results, are boundaries I drew while organizing. Other errors in the organizing are mine. This is a direction, plus engineering problems that are not finished. It is not a completed answer.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>agents</category>
    </item>
    <item>
      <title>A General World Model Is Still Far. Next-State Prediction Already Runs.</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Thu, 08 Oct 2026 08:14:54 +0000</pubDate>
      <link>https://dev.to/zxpmail/a-general-world-model-is-still-far-next-state-prediction-already-runs-1ghm</link>
      <guid>https://dev.to/zxpmail/a-general-world-model-is-still-far-next-state-prediction-already-runs-1ghm</guid>
      <description>&lt;h1&gt;
  
  
  A General World Model Is Still Far. Next-State Prediction Already Runs.
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;2026-10-08&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;World Labs put the phrase back in circulation. Marble turns a picture into a 3D scene you can walk through. Atlas, released in September 2026, is billed as a next-generation world model: text, images, video, and 3D go into one spatial context, and the model generates what comes next. It is meant to power later versions of Marble, and to feed robot simulation.&lt;/p&gt;

&lt;p&gt;It looks as if machines are close to understanding the physical world.&lt;/p&gt;

&lt;p&gt;A general world model is still far away.&lt;/p&gt;

&lt;p&gt;That claim has to be split. Left in one piece, it is either empty pessimism, or the reverse exaggeration: a trajectory predictor in a car, called a finished foundation model.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The name covers three things
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Generative world models.&lt;/strong&gt; Sora, Genie, Marble, Atlas. A picture or a sentence goes in. A video, a 3D scene, or a new camera view comes out. Genie takes actions. Atlas does more than paint the next pixel. It puts several inputs into one spatial representation.&lt;/p&gt;

&lt;p&gt;Looking right is still not understanding. Gravity breaks. Objects vanish. Over a long stretch the scene stops matching itself. The model learns what usually comes next. A larger scale might grow some physical intuition. There is not enough evidence to treat a demo as an ability. There is also no evidence that scaling cannot produce it. Leave both open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next-state prediction already running in engineering.&lt;/strong&gt; This layer is old, and it often does not use the name. Trajectory prediction, occupancy networks, and ego dynamics in driving. Grasp and motion prediction in robots. Cloud simulators that manufacture rare cases and run closed-loop tests. The job is the same: given the state and an action, estimate what happens next.&lt;/p&gt;

&lt;p&gt;Draw the line. Under this definition a bicycle model, a Kalman filter, and the physics engine inside a simulator all count. "World models are already in use" means this function is old. It does not mean a new foundation model is done.&lt;/p&gt;

&lt;p&gt;Occupancy networks and trajectory predictors enter decisions because they write the world as grids, trajectories, and occupancy, and those can be scored. A collision is measurable. A miss is measurable. A generative model leaves the state in the picture, and a mistake often only looks a little odd. Both learn statistics. Both can break physics. The difference is where the state is written, and whether a mistake can be caught.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The general world model.&lt;/strong&gt; This is the one Fei-Fei Li and Yann LeCun are after. One representation that holds 3D space and time, objects, cause, and interaction. It still works in another scene and on another body. It can answer what would have happened if the action had been different. Planning that uses it beats a special-purpose module in a closed loop.&lt;/p&gt;

&lt;p&gt;That one is far.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. "What was seen" does not give "what if I act"
&lt;/h2&gt;

&lt;p&gt;The usual explanation is that data and compute are short, and enough of both will grow the ability. Atlas's own bet is the same: more training compute, more ability.&lt;/p&gt;

&lt;p&gt;That bet is not falsified. It should not be treated as already falsified. Hard only means it cannot be done today.&lt;/p&gt;

&lt;p&gt;The gap that can be stated is narrower. Next-frame training learns what usually follows what was seen. Planning asks what the world does if I take an action that never happened.&lt;/p&gt;

&lt;p&gt;Records of what already happened do not separate the two. A cup falls because I pushed it, or because it slipped. Correlation can look convincing. Telling the cause takes an action, then the result. More samples make "what usually happens" more stable. If the data has no record of acting, intervention and counterfactuals do not appear on their own.&lt;/p&gt;

&lt;p&gt;A few concrete difficulties follow.&lt;/p&gt;

&lt;p&gt;Representation. Geometry, meaning, material, dynamics, and intent still live in different tools. One shared context means the model can read them together. Reading them together is not a representation you can intervene on.&lt;/p&gt;

&lt;p&gt;Interaction. The model has to separate a change I caused from a change the world made on its own. Action has to be a condition, and the actions cannot be only the ones people already took.&lt;/p&gt;

&lt;p&gt;Closed loop. On a robot, in a car, or in AR/MR, trying it yourself is expensive, risky, and full of rare cases.&lt;/p&gt;

&lt;p&gt;Evaluation. Accurate pixels are not correct physics. Physics tests and closed-loop tests exist. They do not line up with each other, and they do not predict whether a system can ship. The missing piece is a standard that matches real action.&lt;/p&gt;

&lt;p&gt;Latency. A car and a robot need low delay, and a failure that can be explained. Today's generative models do not sit in that seat.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Driving is the cleanest test
&lt;/h2&gt;

&lt;p&gt;Some people say autonomous driving does not use a world model. On the vehicle it is perception, prediction, and planning. That is half right.&lt;/p&gt;

&lt;p&gt;The vehicle will not run an explicit generative world model. Compute, latency, safety checks, and the need to explain a failure all forbid it. In that sense, driving does not run that kind of world model.&lt;/p&gt;

&lt;p&gt;The vehicle still cannot do without "what happens next." Trajectory prediction estimates how other vehicles and people move. An occupancy network estimates which space will be taken. A dynamics model estimates how the vehicle responds after an action. Cloud simulation uses the same kind of method to build rare cases and run closed-loop tests. These are narrow predictors, and they can be checked.&lt;/p&gt;

&lt;p&gt;When planning uses dynamic programming or model predictive control, this term is that predictor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;V(s) = min over a of [ R(s, a) + γ Σ P(s' | s, a) V(s') ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A model-free method can skip writing down &lt;code&gt;P(s' | s, a)&lt;/code&gt; and learn the action directly. Closed-loop control depends on how the environment changes, either as an explicit probability or welded into the policy.&lt;/p&gt;

&lt;p&gt;An end-to-end network that drives shows that it reacts to the road. It does not show that a piece can be pulled out and asked, "what if I change lanes now?" Reacting and being available to ask are different things.&lt;/p&gt;

&lt;p&gt;What the car already has is a special-purpose predictor on a narrow state: lanes, vehicles, occupancy. The argument is about another road, another kind of road user, an action never seen, and whether that answer is more reliable than the modules already there.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. AR/MR supplies samples, not the model
&lt;/h2&gt;

&lt;p&gt;AR/MR is often pulled into the same picture. Its value is not a few extra labels. In real 3D space it records, continuously and with position, what the scene was, what the person did, and what the scene became.&lt;/p&gt;

&lt;p&gt;Camera pose, depth, meshes, and point clouds record space. Object class, material, and whether something can be handled record attributes. Gesture, gaze, speech, and grasp trajectories record action. The scene before, during, and after the action records order in time.&lt;/p&gt;

&lt;p&gt;The samples are useful. They are still mostly trajectories of what was seen. Force at contact, mass, and friction are often missing from the picture. AR/MR is a data factory and a proving ground. It is not a general world model.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. How to tell it is getting close
&lt;/h2&gt;

&lt;p&gt;"Far" has to be something that can be proven wrong.&lt;/p&gt;

&lt;p&gt;Long consistency. For minutes, objects remain, physics still holds, and the scene still matches itself.&lt;/p&gt;

&lt;p&gt;Intervention. Given an action, the model predicts how the state changes. A next frame that merely looks reasonable does not count.&lt;/p&gt;

&lt;p&gt;Counterfactuals. What if the action had been different. A harder check: two models can tie on "does the next frame look right" and disagree on "what if I had not done that." A high prediction score does not pin down the counterfactual.&lt;/p&gt;

&lt;p&gt;Closed loop. On a robot or a driving task, planning with the model beats the special-purpose method already in use. This is the ledger. If the earlier items fail, this one does not arrive.&lt;/p&gt;

&lt;p&gt;Physics. Gravity, collision, friction, and occlusion hold steadily, rather than by an occasional lucky guess.&lt;/p&gt;

&lt;p&gt;Cause. It separates occurring together from causing. It supports both "I act" and "what if I had not."&lt;/p&gt;

&lt;p&gt;None of these is stably met for the general case. "Still far" has criteria.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What is actually true
&lt;/h2&gt;

&lt;p&gt;Next-state prediction, as a function, already runs in engineering. The thing called a world model, and expected to be a third foundation model after language models and vision-language models, is early. Across scenes. An action never seen. A counterfactual. A closed loop where it beats a special-purpose module.&lt;/p&gt;

&lt;p&gt;On the vehicle, the stack is still perception, prediction, and planning. Large models carry meaning and reasoning. Next-state prediction sits in a special-purpose module, or is welded into an end-to-end policy. A generative model does not run there on its own.&lt;/p&gt;

&lt;p&gt;In cloud simulation the method is already useful: rare cases, closed-loop tests, synthetic data.&lt;/p&gt;

&lt;p&gt;AR/MR is a source of data and a place to check.&lt;/p&gt;

&lt;p&gt;Robots are the closest proving ground, and the least mature. Here the system has to act and then see the result. "What was seen" and "I acted" start to come apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  7.
&lt;/h2&gt;

&lt;p&gt;Two extremes are both wrong in the same way. Each one flattens the word.&lt;/p&gt;

&lt;p&gt;One says a world model is about to change everything. A demo is treated as an ability. Generation is treated as understanding.&lt;/p&gt;

&lt;p&gt;The other says a world model is hype and useless, and throws out the predictors already running in cars and simulators.&lt;/p&gt;

&lt;p&gt;The direction is right. Representation, prediction, and action in the physical world are a main line after language models and vision-language models. The work will enter driving, robots, and AR/MR in pieces, by domain, sometimes as its own module and sometimes welded into a policy. It will not arrive one day as a single general model and rewrite the rest.&lt;/p&gt;

&lt;p&gt;Maturity is three questions. Can the world be written as a state a program can use. Can change be predicted reliably. Can the system act safely on that prediction.&lt;/p&gt;

&lt;p&gt;On a narrow task, a lane or a grasp, usable versions of all three already exist. Change the body, the physics, or the action to one never seen, and all three break.&lt;/p&gt;

&lt;p&gt;The third question is the watershed. The first two can stop at "looks real." The third requires the answer to be right, because a wrong action causes harm. In the general sense, that watershed is still far.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>robotics</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Ontology, Gates, and a Human Backstop: Three Defenses for Enterprise AI That Don't Spin Empty</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Mon, 05 Oct 2026 11:12:50 +0000</pubDate>
      <link>https://dev.to/zxpmail/ontology-gates-and-a-human-backstop-three-defenses-for-enterprise-ai-that-dont-spin-empty-3bdo</link>
      <guid>https://dev.to/zxpmail/ontology-gates-and-a-human-backstop-three-defenses-for-enterprise-ai-that-dont-spin-empty-3bdo</guid>
      <description>&lt;h1&gt;
  
  
  Ontology, Gates, and a Human Backstop: Three Defenses for Enterprise AI That Don't Spin Empty
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;2026-10-05&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Enterprise AI usually lands in one of two extremes.&lt;/p&gt;

&lt;p&gt;One side says: build the ontology and the AI will understand. The other says: an ontology is soft, it cannot hold the line, and what matters is gates plus a human backstop.&lt;/p&gt;

&lt;p&gt;Each side is only half right.&lt;/p&gt;

&lt;p&gt;An ontology makes it possible for the AI to get it right. A gate makes it hard for the AI to do the wrong thing on its own. A human backstop keeps a mistake from becoming a disaster. Use the three together, and close the loop: the ontology hands objects and rules to the gate, the gate hands anything out of bounds to a person, and after the person handles it they ask whether a term or a threshold should change. Without that return path, people keep putting out the same fire.&lt;/p&gt;

&lt;p&gt;The weight shifts with the scene. The short board sets the ceiling. High frequency, low risk, reversible: the ontology and automated gates set the experience and the cost. Low frequency, high risk, irreversible: the gate and the human backstop are what keep you safe. Heavy regulation and heavy responsibility: all three have to be hard. Open questions can tolerate a wrong answer. Data that should not enter the context still has to be stopped.&lt;/p&gt;

&lt;p&gt;Whether this works is not a question of whether the article is complete. It is whether the three tables can be filled in for one concrete scene. A cell you cannot fill means that question may not be answered, and that action may not be taken.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What each layer handles
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it handles&lt;/th&gt;
&lt;th&gt;When it fails&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ontology&lt;/td&gt;
&lt;td&gt;Whether the system understands&lt;/td&gt;
&lt;td&gt;The answer is fluent, and wrong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gate&lt;/td&gt;
&lt;td&gt;Whether it may, and whether the figure is the right one&lt;/td&gt;
&lt;td&gt;It acts at random, exceeds its authority, or does something irreversible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human backstop&lt;/td&gt;
&lt;td&gt;Who is responsible, and how a mistake is written back&lt;/td&gt;
&lt;td&gt;The damage cannot be undone, and the same kind of mistake keeps returning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not ask which layer matters most. Ask which layer is the short board in this scene, then ask whether that layer's table is filled in.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Ontology: start from a specification
&lt;/h2&gt;

&lt;p&gt;An ontology here is a business specification: what a word means, what it does not mean, and which field on which document the figure comes from. It is soft, like an employee handbook. It does not itself block an action. The part that can be made hard has to become a check outside the model.&lt;/p&gt;

&lt;p&gt;Split the content into two kinds first:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;Where it lives&lt;/th&gt;
&lt;th&gt;What a mistake does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Helps the model choose the right meaning&lt;/td&gt;
&lt;td&gt;Terms, relations, definitions. The model may read them&lt;/td&gt;
&lt;td&gt;The wording drifts, and can still be corrected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Must not be allowed to happen&lt;/td&gt;
&lt;td&gt;Written as a program check&lt;/td&gt;
&lt;td&gt;The action cannot occur&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"Collected payment is not the invoice amount" is the first kind. Putting the words in a table does not stop the model from answering with the invoice amount. A wrong figure is stopped by the input gate: what is handed to the model this time contains only the field named on the authoritative source. The invoice amount is not included.&lt;/p&gt;

&lt;p&gt;"Do not send it to the customer on their behalf" and "do not pay above this amount" are the second kind. Written into the prompt for the model to obey on its own, they are still soft.&lt;/p&gt;

&lt;p&gt;Each common word gets four lines: how people say it, what it is, what it is not, and which field on which document is the authoritative source. "What it is not" matters most.&lt;/p&gt;

&lt;p&gt;One word binds to one authoritative source. If a finance definition and a management definition are both legitimate, they are two words. Do not switch sources on the same word. When two owners disagree, follow the owner of this word, the person on the side of the authoritative source. When the definition changes, new documents use the new version. Documents that already happened keep the old version.&lt;/p&gt;

&lt;p&gt;If the source has no record yet, the answer is "no figure yet." Do not fill it from another set of books. Also write how long the business can wait. If the wait expires and there is still no figure, point to a named person. Do not repeat the same sentence. If the wait is not written down, people will go look somewhere else, and this gate has nobody walking through it.&lt;/p&gt;

&lt;p&gt;Write only relations that have actually been asked. Three to five is enough. Write the rules, and mark which kind each one is. A rule of the second kind lands on a gate at that moment.&lt;/p&gt;

&lt;p&gt;Each word has an owner, an update trigger, a version, and a minimum set. It also has a reviewer and a review cycle. A trigger without a review lets the table go stale when nobody reports an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Gates: start from what is forbidden
&lt;/h2&gt;

&lt;p&gt;Write what must never be done: which fields cannot be changed, which approvals cannot be skipped, what cannot be sent outside, which tools cannot be called, and above what amount a person is required. Talk about permission only outside that forbidden zone.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What the system does&lt;/th&gt;
&lt;th&gt;What the person does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read only&lt;/td&gt;
&lt;td&gt;Looks up and answers&lt;/td&gt;
&lt;td&gt;Judges for themselves&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suggestion&lt;/td&gt;
&lt;td&gt;Offers a suggestion&lt;/td&gt;
&lt;td&gt;Does the thing themselves, including sending it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirmation&lt;/td&gt;
&lt;td&gt;After the person agrees, the system does it&lt;/td&gt;
&lt;td&gt;Agrees, and is responsible for what cannot be undone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;Does it directly, and leaves a trace&lt;/td&gt;
&lt;td&gt;Can be inspected afterward, and can be rolled back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forbidden&lt;/td&gt;
&lt;td&gt;Does not do it&lt;/td&gt;
&lt;td&gt;Not applicable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Anything not explicitly allowed is forbidden. If read-only is enough, do not grant a write. An automatic action must be reversible or have a remedy. The judgment sits outside the model. Waiting for a person has a time limit. When the time is up, the action stops. A stop is not the same as a person refusing, and it must not be turned into an automatic action.&lt;/p&gt;

&lt;p&gt;Use the checkpoints the scene needs. All seven are not required:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Checkpoint&lt;/th&gt;
&lt;th&gt;What the program does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Input gate&lt;/td&gt;
&lt;td&gt;Which documents and which fields are allowed this time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Term gate&lt;/td&gt;
&lt;td&gt;Checks an allowlist. Which words a conclusion may use is written in advance, and so is which slots the output has&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool gate&lt;/td&gt;
&lt;td&gt;Which tools may be called, and whether the parameters are allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action gate&lt;/td&gt;
&lt;td&gt;Which fields may change, and which states may move&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Approval gate&lt;/td&gt;
&lt;td&gt;Above a threshold, across parties, or outside the country, hand it to a person&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provenance gate&lt;/td&gt;
&lt;td&gt;Compares only fields that have already been written down with the authoritative source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit gate&lt;/td&gt;
&lt;td&gt;Who let it through, when, which version of the terms, which document&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The term gate does not guess afterward which word the conclusion depended on. That falls back to letting the model judge for itself. The allowlist and the output shape are written first.&lt;/p&gt;

&lt;p&gt;The provenance gate compares fields only. In collections, the amount, the customer, and the invoice number can be cells. The suggested wording is not compared. An analysis, a long conclusion, or a judgment tangled in several conditions cannot be made into stable fields, so do not install this gate there. Those scenes keep the input gate, the forbidden zone, and the audit. The conclusion stays with a person.&lt;/p&gt;

&lt;p&gt;A confidence score the model reports about itself is not a gate.&lt;/p&gt;

&lt;p&gt;To rise from "the system acts after a person agrees" to "the system acts on its own," write five things first. The count comes last:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What counts as one error. If that is not written, a count means nothing&lt;/li&gt;
&lt;li&gt;Who decides it was an error. What they check against, and how much time is set aside for that check. If nobody decides, the action stays at its current level. A name with no time is only a stamp&lt;/li&gt;
&lt;li&gt;The sample has to cover the main situations of this kind of action. A pile of easy cases is not enough, even if the count is large&lt;/li&gt;
&lt;li&gt;The action can be undone, or has a stated remedy&lt;/li&gt;
&lt;li&gt;If it errs again, it drops back one level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Low-frequency, high-risk, irreversible actions do not become automatic by accumulating a count.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The human backstop: the last layer
&lt;/h2&gt;

&lt;p&gt;It has to exist. It cannot be the main path. People are expensive, they get tired, and they spread the responsibility thin.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Exception handling&lt;/td&gt;
&lt;td&gt;Handles what a gate stopped, and what the program cannot match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responsibility&lt;/td&gt;
&lt;td&gt;Signs for an irreversible action&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Return path&lt;/td&gt;
&lt;td&gt;Decides whether the terms change, or the gate changes. If neither changes, write the reason&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Escalate only when the case hits the allowlist, an approval, or provenance. Each backstop has a handler, a time limit, a next person, and someone who counts whether the time was exceeded. If nobody counts, the time limit is empty.&lt;/p&gt;

&lt;p&gt;While the system only suggests and the person does the thing themselves, whether the amount was stated wrong is compared by the program. Do not ask another department to certify the sending. Certification is only for what the program cannot see: a source delay the business will not accept, or a disputed definition. Once the system sends on its own, a sending error needs a separate person to certify it, and that person needs the time above.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Fill the tables once, with collections
&lt;/h2&gt;

&lt;p&gt;The scene is fixed. A salesperson asks about a customer's collected payment. The system answers from the finance receipt only, with an amount and a suggested wording. The salesperson decides whether to send it, and sends it themselves. This is a suggestion. It is not "the system sends after someone nods."&lt;/p&gt;

&lt;p&gt;This scene has four output slots: customer, booked amount, whether anything is still unbooked, and suggested wording. The only conclusion word on the allowlist is "collected payment."&lt;/p&gt;

&lt;p&gt;What can be filled in:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What collected payment is&lt;/td&gt;
&lt;td&gt;Money the customer actually paid into the company account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What it is not&lt;/td&gt;
&lt;td&gt;Not the invoice amount, not the contract amount, and it does not include prepayment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input&lt;/td&gt;
&lt;td&gt;Only the booked amount on the receipt. The invoice amount is not included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sending&lt;/td&gt;
&lt;td&gt;No send tool. The system does not change the document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provenance&lt;/td&gt;
&lt;td&gt;Compare only the customer and the booked amount. Do not compare the wording&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unbooked&lt;/td&gt;
&lt;td&gt;Say "no figure yet." Do not fill it with some other number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Level&lt;/td&gt;
&lt;td&gt;Stays at suggestion. It does not rise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Empty, and therefore not allowed yet:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Empty cell&lt;/th&gt;
&lt;th&gt;Therefore not allowed yet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Which system holds the receipt, and which field&lt;/td&gt;
&lt;td&gt;The input gate cannot be drawn, so the amount cannot yet be a formal answer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How a customer id matches a receipt&lt;/td&gt;
&lt;td&gt;Do not answer "this customer's collected payment"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How an invoice matches a payment received&lt;/td&gt;
&lt;td&gt;Do not answer "whether this invoice has been paid"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Which day overdue starts, and after how many days it counts&lt;/td&gt;
&lt;td&gt;Do not answer about overdue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How late the source may be&lt;/td&gt;
&lt;td&gt;"No figure yet" cannot go live yet, or people will go around it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who handles a mismatch, how long, whom they call, who counts timeouts&lt;/td&gt;
&lt;td&gt;The backstop is only a name so far&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who reviews the three tables, and how often&lt;/td&gt;
&lt;td&gt;The tables are not built yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What counts as one error&lt;/td&gt;
&lt;td&gt;The system does not send on its own yet, so this may stay empty. It must exist before the system sends&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A management definition is a different word. This scene does not ask it, so that row is not built.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Different scenes trim the tables
&lt;/h2&gt;

&lt;p&gt;The three tables are one way of filling things in. They are not a full copy for every line of business.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scene&lt;/th&gt;
&lt;th&gt;How the tables are used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Documents, processes, and fields are clear&lt;/td&gt;
&lt;td&gt;The input gate, the allowlist, the provenance gate, and the audit gate can be used together&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low frequency, high risk, irreversible&lt;/td&gt;
&lt;td&gt;Keep the forbidden zone, approval, and a signature. Do not schedule automatic action&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open questions, analysis reports&lt;/td&gt;
&lt;td&gt;Keep the input gate, the forbidden zone, and the audit. Do not turn provenance into fields. A person owns the conclusion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy regulation, accountability required&lt;/td&gt;
&lt;td&gt;Every row used above needs a version, a person who certifies, and a review&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Consider automatic action only for something that can be undone, and only after "what counts as one error" is already written.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Order of landing
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pick one scene. Write the terms and the forbidden zone first. Mark which of the two kinds each rule is.&lt;/li&gt;
&lt;li&gt;Fill the three tables. A question you cannot fill in is removed from what may be answered.&lt;/li&gt;
&lt;li&gt;Go live as read-only. Use a fixed set of questions to see whether the error is the definition, the wrong field, or a missing source.&lt;/li&gt;
&lt;li&gt;Suggestion: the system suggests, the person acts.&lt;/li&gt;
&lt;li&gt;Confirmation: the system acts after a person agrees. The person who certifies, the time limit, and the person who counts timeouts already exist.&lt;/li&gt;
&lt;li&gt;The error definition, the sample, and the rollback are written before automatic action is considered.&lt;/li&gt;
&lt;li&gt;Every backstop returns. On the review day, look for a stale table even if nobody reported an error.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those are the column headers. Delete rows the scene does not use. Do not leave a gate that nobody walks through.&lt;/p&gt;

&lt;p&gt;Ontology: term or rule, kind, definition, what it is not, authoritative source and field, owner, how to answer when there is no record yet, how long to wait, update trigger, version, reviewer and cycle.&lt;/p&gt;

&lt;p&gt;Gate: checkpoint, rule, where the line is drawn, what happens after a stop, who agrees, who certifies an error, what happens when time is up, the log, whether it can be undone, the error definition required before a level rises, rollback, reviewer and cycle.&lt;/p&gt;

&lt;p&gt;Backstop: what was hit, who handles it, how long, whom they call if they cannot, whether the term changes or the gate changes, whether it was finished, who counts timeouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Close
&lt;/h2&gt;

&lt;p&gt;An ontology lets the AI know the business. A gate keeps the AI from acting at random. A human backstop keeps a mistake from becoming a disaster. The return path keeps the same kind of mistake from repeating.&lt;/p&gt;

&lt;p&gt;If the tables for one scene cannot be filled in, the three layers are not there yet. The empty cells are the boundary of this defense.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>data</category>
    </item>
    <item>
      <title>Weld the Tenant Boundary on the Server</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Thu, 01 Oct 2026 12:55:50 +0000</pubDate>
      <link>https://dev.to/zxpmail/weld-the-tenant-boundary-on-the-server-df6</link>
      <guid>https://dev.to/zxpmail/weld-the-tenant-boundary-on-the-server-df6</guid>
      <description>&lt;h1&gt;
  
  
  Weld the Tenant Boundary on the Server
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Subtitle: A reported name can be noted. It cannot be trusted blindly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2026-10-01&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a multi-tenant system, the cheap path is: the request path names an org, the token names an org, and the model passes an org again when it calls a tool. If the three agree, the data is treated as belonging to that tenant.&lt;/p&gt;

&lt;p&gt;All three can be swapped. The path can point at someone else's org. The claim in the token can be only a hint. The model can fill in a different repo in its arguments. The cheap path treats "who reported the name" as "whose data this is."&lt;/p&gt;

&lt;p&gt;This piece is only about how data is isolated. The per-layer rules and examples stay in the reference draft. They are not repeated here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Binding happens on the server
&lt;/h2&gt;

&lt;p&gt;A request may name an org, a project, and a repo. The claim in the token is only a hint. What counts is that the server finds "this person is actually a member of that scope," and only after that row comes back does it mint the context for this request.&lt;/p&gt;

&lt;p&gt;Business code must not mint that context by hand. Minting happens at the entrance. Later functions take the context. They do not take identifier strings from the caller.&lt;/p&gt;

&lt;p&gt;Org, project, repo, index, object key, and topic supplied inside a model tool call are dropped and written back from the context. If the model disagrees with the context, write an audit row and still execute against the context. Do not keep the model's value as a fallback.&lt;/p&gt;

&lt;p&gt;Every data plane gets its tenant filter from the server. Tenant fields in the client, the URL, and the model arguments are not used.&lt;/p&gt;

&lt;h2&gt;
  
  
  The convenient leak is on the corpus
&lt;/h2&gt;

&lt;p&gt;Two repos inside one org reading each other is a common leak in a coding assistant. Isolating business data such as orders by org does not stop this plane. Vectors, code objects, search, and repo caches have to be isolated by org and repo together. One tenant id pushed through every layer makes those two repos share one corpus.&lt;/p&gt;

&lt;p&gt;The other cheap path is to check the token and skip the membership lookup, or to let a repo name in the tool arguments override the context. That implementation has to fail a negative test: cross tenants once on purpose, and the detector must catch it. A fully green suite does not show that the detector is wired in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this piece does not cover
&lt;/h2&gt;

&lt;p&gt;How keys are generated, where they live, and how they rotate are not here. Whether the model vendor keeps prompts, or trains on them, is not here either.&lt;/p&gt;

&lt;p&gt;Making ciphertext in backups unreadable, and actually deleting data on the vendor side, each needs its own procedure. This piece stops at: delete online data inside the scope the server already bound, and record the vendor's ticket number for the deletion request. The contract, zero-retention, and which region the data sits in are not spelled out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;People weld the tenant on the server: bind only after the membership check, and drop the names reported by the client and the model. The convenient leak is two repos in one org sharing a corpus, or letting the caller name the tenant. Keys and vendor retention are not in this piece.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
      <category>database</category>
    </item>
    <item>
      <title>Don't Treat 'Module Internals Don't Matter' as Unconditional</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Tue, 29 Sep 2026 11:38:31 +0000</pubDate>
      <link>https://dev.to/zxpmail/dont-treat-module-internals-dont-matter-as-unconditional-549o</link>
      <guid>https://dev.to/zxpmail/dont-treat-module-internals-dont-matter-as-unconditional-549o</guid>
      <description>&lt;h1&gt;
  
  
  Don't Treat "Module Internals Don't Matter" as Unconditional
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Subtitle: Urgency raises soft boundaries. A rules file pushes back behavior, not understanding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2026-09-29&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The essay &lt;em&gt;Why the Best Software Advice Is the Hardest to Follow&lt;/em&gt; splits advice into two kinds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Practical advice:&lt;/strong&gt; small functions, no magic numbers, clear names. Teachable. Checkable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judgment advice:&lt;/strong&gt; a wrong abstraction costs more than duplication; keep it simple; don't repeat yourself. No standard answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The conclusion is that the most valuable advice is the hardest to follow, because it is judgment, not a rule. I agree.&lt;/p&gt;

&lt;p&gt;In the AI era I want one tighter limit:&lt;/p&gt;

&lt;p&gt;People should move their attention up to the business, the cut, the boundary, and the contract. The inside of a module can be handed to AI more often.&lt;br&gt;&lt;br&gt;
But "duplication or abstraction inside the module doesn't matter, the AI understands" — the direction is right, and it &lt;strong&gt;must not be said as if it were unconditional&lt;/strong&gt;. "Unconditional" here means treating it as a slogan that always holds.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The direction is right: move human attention up
&lt;/h2&gt;

&lt;p&gt;Human attention is limited. If you spend the day arguing whether a function is over 20 lines, whether a name is good enough, or whether to extract an interface, you sink into the local and miss what actually decides the outcome:&lt;/p&gt;

&lt;p&gt;What business problem is this? What is the core domain? How is the system cut? Where is the boundary? Who owns the data? Which way do dependencies point? What is the contract? Which changes must be isolated? Which decisions are irreversible? Who carries the risk?&lt;/p&gt;

&lt;p&gt;Get those wrong, and pretty code will not save you.&lt;br&gt;&lt;br&gt;
So: people own business clarification, domain cuts, module boundaries, and contracts. How the inside repeats or abstracts can be delegated to AI more often.&lt;/p&gt;

&lt;p&gt;On that part, I agree.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. "Doesn't matter" has a premise. Urgency is more dangerous than "AI nature"
&lt;/h2&gt;

&lt;p&gt;A typical failure: the team hands almost all in-module implementation to AI. It is fast. There are no contract tests, and no one has defined data ownership. Two modules, for convenience, both read and write the same table. On the surface this is "freedom inside the module." In fact they are quietly coupled through a shared table. Later one module changes what a field means. The other module's transaction boundary fails. The data diverges. Rollback does not come clean.&lt;/p&gt;

&lt;p&gt;The problem is not that the inside is ugly. The problem is that &lt;strong&gt;the boundary was never actually hard&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Teams that do this well usually write the core interface schema, acceptance criteria, and data ownership into a rules file first. After that, however the AI-generated inside repeats or abstracts, the contract still holds it. The difference is not whether someone "uses AI well." It is whether the boundary was welded shut beforehand.&lt;/p&gt;

&lt;p&gt;So this sentence holds only when the boundary is hard enough:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Inside the module, duplication or abstraction can be highly delegated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And one more sentence, so it is not said unconditionally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;High delegation is not zero constraint. Readability, testability, and performance and security budgets remain the floor inside the module.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I originally wanted a fuller sentence: "AI systematically rewards soft boundaries." After a small reproducible experiment, that sentence had to be tightened — and the claim got harder, not softer.&lt;/p&gt;

&lt;h3&gt;
  
  
  A small reproducible experiment
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Original claim:&lt;/strong&gt; with no extra constraint, AI more often picks the soft boundary (reaching into another module's table).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method:&lt;/strong&gt; 3 cross-module tasks (order email snapshot / inventory marks an order shipped / billing reads a phone number) × each task A = soft (direct SQL/ORM) or B = hard (API or event) × 3 contexts (bare / speed, which urges "ship soon, change little" / hard, which writes data-ownership rules) × N=5, temperature=0.7. First run locally on qwen2.5:7b, then retested through the current Claude provider on cc-switch (glm-5.3-flash).&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/zxpmail/blog/blob/main/agent-determinism-illusions/scripts/soft-boundary-bias-test.py" rel="noopener noreferrer"&gt;soft-boundary-bias-test.py&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;bare&lt;/th&gt;
&lt;th&gt;speed&lt;/th&gt;
&lt;th&gt;hard&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;qwen2.5:7b (Ollama)&lt;/td&gt;
&lt;td&gt;0% (0/15)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;33%&lt;/strong&gt; (5/15)&lt;/td&gt;
&lt;td&gt;0% (0/15)&lt;/td&gt;
&lt;td&gt;SUPPORT_SPEED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;glm-5.3-flash (cc-switch / Zhipu)&lt;/td&gt;
&lt;td&gt;0% (0/15)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;73%&lt;/strong&gt; (11/15)&lt;/td&gt;
&lt;td&gt;0% (0/15)&lt;/td&gt;
&lt;td&gt;SUPPORT_SPEED&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same shape on both models: bare and hard never pick soft; urgency lifts it. Speed is higher on GLM, but both are small samples (15 trials per condition). Do not extrapolate the size of the gap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tighten the conclusion once more:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bare 0% is not "AI defaults to the hard boundary."&lt;/strong&gt; It only says: when both options are laid out clearly and there is no time pressure, the model showed no soft-boundary preference. That is already enough to correct "systematically rewards soft boundaries."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;speed is the only clear signal.&lt;/strong&gt; On qwen, all 5 soft picks fell on S3. On GLM the soft picks were more scattered (11/15), and the rate was higher. Fifteen trials per condition cannot be generalized, and 33% vs 73% is not a ranking of which model is worse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hard 0% shows that a rules file works, with a caveat:&lt;/strong&gt; the model may be obeying the rule, not understanding the boundary. What the rule pushes back is behavior, not necessarily judgment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This run did not separate "ship soon" from "change little." Time pressure and change-suppression were written into the same urgency condition.&lt;/p&gt;

&lt;p&gt;Closer to the data, under this setup:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When both options are clear, the model does not necessarily reach for the soft boundary.&lt;br&gt;&lt;br&gt;
Once you add "ship soon / change little," soft-boundary picks rise.&lt;br&gt;&lt;br&gt;
Writing data ownership into the rules can push that rise back down.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This correction is stronger than the original sentence. The problem sits on &lt;strong&gt;the low-friction shortcut under urgency&lt;/strong&gt;, not on an abstract "bad AI." That is a more concrete reason to put the rules file first — not to defend against AI itself, but to block the shortcut AI takes under pressure.&lt;/p&gt;

&lt;p&gt;A boundary is hard enough to delegate across when, typically: the interface contract is clear, invariants are explicit, data ownership is clear, dependency direction is controlled, boundary and contract tests are sufficient, performance and security have explicit requirements, and there is no cross-module shared write or hidden coupling.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to make the boundary hard enough: a minimal sufficient set
&lt;/h2&gt;

&lt;p&gt;Most teams do not need all of this at once. In the experiment, hard pushed soft back to 0%. That is reason enough to put the rules file first — just do not read obedience as understanding.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Means&lt;/th&gt;
&lt;th&gt;When&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rules file&lt;/td&gt;
&lt;td&gt;Now&lt;/td&gt;
&lt;td&gt;Default, required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data ownership&lt;/td&gt;
&lt;td&gt;Now (an organizational decision is enough)&lt;/td&gt;
&lt;td&gt;Default, required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spec before code&lt;/td&gt;
&lt;td&gt;When rework is frequent&lt;/td&gt;
&lt;td&gt;On signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contract tests&lt;/td&gt;
&lt;td&gt;Modules ≥ 3, or interfaces change often&lt;/td&gt;
&lt;td&gt;On signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture guardrails&lt;/td&gt;
&lt;td&gt;People ≥ 10, or dependencies are out of control&lt;/td&gt;
&lt;td&gt;On signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fitness functions&lt;/td&gt;
&lt;td&gt;After the earlier items are stable&lt;/td&gt;
&lt;td&gt;A monthly report can stand in for now&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Minimal sufficient set: rules file + data ownership + a contract on the core interfaces.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The rest fires on signal. The order must not be reversed. Write the rules into &lt;code&gt;.cursorrules&lt;/code&gt; / &lt;code&gt;CLAUDE.md&lt;/code&gt;. A table or an event has one write path. Contracts and guardrails fail in a tool. They do not depend on someone remembering.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. "The AI will understand" is not enough: feed context by risk
&lt;/h2&gt;

&lt;p&gt;AI depends on context, not on unspoken agreement. More context is not always better.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;High risk / irreversible&lt;/th&gt;
&lt;th&gt;Low risk / reversible&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Glossary / constraints&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Minimal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ADRs / failure cases&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Summary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contract / acceptance&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Core schema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human review&lt;/td&gt;
&lt;td&gt;Small steps&lt;/td&gt;
&lt;td&gt;Automated tests + fast rollback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;High risk gets the full feed and a human review. Low risk gets the minimum, with automation as the backstop.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. What humans review: watch for abnormal signals
&lt;/h2&gt;

&lt;p&gt;People own seams and contracts. AI owns implementation. You are not reviewing every line. You are watching whether these signals get worse:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Abnormal signal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Module boundary&lt;/td&gt;
&lt;td&gt;One PR often touches 3–4 modules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interface contract&lt;/td&gt;
&lt;td&gt;Breaking changes with no version; idempotency with no test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invariants&lt;/td&gt;
&lt;td&gt;Core invariants with no test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependency direction&lt;/td&gt;
&lt;td&gt;Reverse dependencies and cycles rising&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data ownership&lt;/td&gt;
&lt;td&gt;Multiple writers on one table; cross-module SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-functional / evolution&lt;/td&gt;
&lt;td&gt;No SLO, high-risk items still open; cross-module changes and shared-table use trending worse&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  6. Judgment can be written down. Don't turn it into a new dogma
&lt;/h2&gt;

&lt;p&gt;ADRs, failure cases, "when this principle does not apply," reversibility — these can be written for the AI and for the next person. A good form is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At this risk level, we tend to …. If the following signals appear, judge again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rules and tests are constraints a machine can execute. ADRs and cases are preferences a person can update. "Functions must be under 20 lines" kills the judgment again.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Different teams, different moves
&lt;/h2&gt;

&lt;p&gt;One principle: hold the floor at low cost. Do not pile on tools.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Do&lt;/th&gt;
&lt;th&gt;Hold off&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1–3 people&lt;/td&gt;
&lt;td&gt;Minimal rules + data ownership&lt;/td&gt;
&lt;td&gt;Guardrails, full contracts, fitness functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5–20 people&lt;/td&gt;
&lt;td&gt;Rules + ownership + a spec for large changes + core contracts + light guardrails&lt;/td&gt;
&lt;td&gt;Fitness functions (a monthly report instead)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20+ / microservices&lt;/td&gt;
&lt;td&gt;Add weight on signal&lt;/td&gt;
&lt;td&gt;Governance for its own sake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legacy&lt;/td&gt;
&lt;td&gt;Leave the stock alone, align the increment; trends before heavy tools&lt;/td&gt;
&lt;td&gt;A full rewrite on day one&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The tradeoffs: strict on the new, light on the old; strict on the core, light on the edge; strict on high risk, light on low risk; light on the stock, strict on the increment.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. How an ordinary person grows the skill
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Before each module, write three lines:&lt;/strong&gt; What is it responsible for? Who owns the data? Who may call it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After each refactor, record one judgment:&lt;/strong&gt; situation / options / decision / reason / consequence / reversibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each time you use AI, check the boundary once:&lt;/strong&gt; a direct cross-module call? writing someone else's table? bypassing the interface?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The skill of writing code is getting cheaper. The skill of defining a boundary is getting more valuable. You do not leave the code. You stand higher, and you bring the code experience with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The direction is right: people should care about the business, the cut, the boundary, and the contract. The inside of a module can be handed to AI more often.&lt;/p&gt;

&lt;p&gt;Two limits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The boundary is hard enough, the contract is clear enough, the tests are enough&lt;/strong&gt; — under urgency, especially, use rules to block the low-friction shortcut. That is what the experiment supports, not "AI is soft by nature." What a rules file pushes back is behavior, not understanding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feed context by risk&lt;/strong&gt; — not "it will understand," but "give it the right constraint."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;People own the boundary and the intent. AI owns the implementation and the local optimization. The inside can be highly delegated, but it stays under the boundary, the tests, and the budgets for readability, testability, performance, and security.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>agents</category>
      <category>boundaries</category>
    </item>
    <item>
      <title>Experience Admission for White-Box Agentic RL: A Position on Dataflow between Exploration and the Base Policy</title>
      <dc:creator>zxpmail</dc:creator>
      <pubDate>Thu, 24 Sep 2026 10:27:41 +0000</pubDate>
      <link>https://dev.to/zxpmail/experience-admission-for-white-box-agentic-rl-a-position-on-dataflow-between-exploration-and-the-3b4e</link>
      <guid>https://dev.to/zxpmail/experience-admission-for-white-box-agentic-rl-a-position-on-dataflow-between-exploration-and-the-3b4e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Sixth and final in a six-part series on what building with AI agents did to one developer. The last piece ended under a blinking cursor in an empty title; this piece is that file: proposals marked as proposals, failure conditions written before the run.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Version:&lt;/strong&gt; v0.19.3 · 2026-09-24 (aligns abstract with §6.4; separates &lt;code&gt;r&lt;/code&gt; routing from update ban; clarifies &lt;code&gt;ℓ&lt;/code&gt; timing before θ)&lt;br&gt;
&lt;strong&gt;Genre:&lt;/strong&gt; Technical position paper&lt;br&gt;
&lt;strong&gt;Channel note:&lt;/strong&gt; The author is a newcomer. arXiv (cs.LG endorsement) and the SEA Workshop (venue bar) were both blocked as channels, so this paper is published through neither, and no "submitted / forthcoming" claim is made. The claims and the falsification protocol stand alone, independent of any academic venue.&lt;/p&gt;


&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;white-box observable-worker&lt;/strong&gt; multi-worker RL, a layer is often missing between the optimizer and the collaboration interface: &lt;strong&gt;after trajectories are produced, who may materialize, at what granularity, and when θ may update&lt;/strong&gt;. Black-box APIs are outside the strong-form claim.&lt;/p&gt;

&lt;p&gt;This paper calls that layer &lt;strong&gt;experience admission control&lt;/strong&gt; (below, the &lt;strong&gt;admission policy&lt;/strong&gt;). The novelty sits in &lt;strong&gt;P1–P4&lt;/strong&gt; (a proposed admission policy) and preregistered failure conditions — not in a new score or a proven finding. Hypothesis-level claim: the bottleneck is often how experience is layered, isolated, and let into the base update path at low frequency — not more models seeing each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layered verdict:&lt;/strong&gt; fix 𝒜, vary only the data plane (A/B/P). No failure condition (1–5) fires, effective-materialization-ratio improvement ≥ 10% vs A, and return not persistently below A (condition 3 unfired) → &lt;strong&gt;§6.4 scale-up gate&lt;/strong&gt; (may scale up; ≠ validated; ≠ must be a first-class module). If it still passes after scale-up → recommend building it as a first-class pipeline module; otherwise withdraw that configuration's strong form (the name may be retired).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keywords:&lt;/strong&gt; experience admission; proposed admission policy; white-box multi-worker RL; dataflow; falsification&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Discussions of multi-worker, asynchronous, long-horizon RL often conflate three question layers.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;optimization layer&lt;/strong&gt; asks how gradients are computed and applied (e.g., group-relative methods [2], single-rollout asynchronous optimization [1]). The &lt;strong&gt;collaboration layer&lt;/strong&gt; asks how multiple workers share context, files, and session state during interaction. The &lt;strong&gt;admission layer&lt;/strong&gt; answers something else: after a trajectory has been generated, who may materialize it, at what granularity, and when θ may update.&lt;/p&gt;

&lt;p&gt;The optimizer answers "when/how to update." The collaboration interface answers "how to coordinate." Neither directly defines admission semantics. Rising throughput can still expose noise and high-risk trajectories indiscriminately; shared context does not automatically yield isolation rules. &lt;strong&gt;Training stability is related to admission semantics but not identical to it:&lt;/strong&gt; stability asks whether updates on a given visible set diverge; admission asks which trajectories may enter that visible set, and whether/how they are materialized first. An optimizer can learn to be more stable on a dirty visible set — it still does not answer the policy boundary of the visible set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope (narrow first, then motivate).&lt;/strong&gt; The strong form of this paper assumes workers can expose one of: hidden representations, local action distributions, or uncertainty signals. This covers self-deployed open weights and observable actor–learner setups. It does &lt;strong&gt;not&lt;/strong&gt; cover mainstream closed API agents — those degrade, at most, into post-hoc text filtering, are &lt;strong&gt;never conflated with the strong form, and are outside the claim&lt;/strong&gt;. LLM agents are one motivating scenario; the validation domain is the white-box observable setting.&lt;/p&gt;

&lt;p&gt;In that setting the problem is not LLM-specific: long trajectories, asynchrony, and heterogeneous workers exist in classic deep RL too. IMPALA [5] and Hou et al. [1] live on the optimization/scheduling plane, where "delivered ⇒ learnable" can be the default. What this paper names is the &lt;strong&gt;admission policy&lt;/strong&gt; after delivery. Shielding [9] shrinks action feasibility; CQL [6] constrains value estimates on a given dataset — neither answers layered materialization/update budgets on an online stream.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C1, a minimal counterexample (why "having PER on" is not enough).&lt;/strong&gt; Suppose the buffer holds an ordinary learnable trajectory τ⁺ and a high-risk, high-TD-error / high-surprise τ‡. When PER [3] reweights by TD-error and τ‡ sits in a high-priority quantile, it can be sampled into the update batch at above-uniform rates; a rollout-time shield that blocks unsafe &lt;em&gt;actions&lt;/em&gt; does not remove τ‡ from the training-visible set; deletion-style filtering discards its analysis value. Gap triad: P1 budget semantics absent (the trajectory is already in the pool and learnable by default — no "materialize-off-by-default" constraint) / violates P2·P4 / violates P3. The semantic gap: sampling weights ≠ admission policy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; PER's sampling probability follows a power law in the priority quantile, so a high quantile does not guarantee a draw; but the reweighting mechanism in principle allows high-risk samples to reach the learner above uniform rates — this mechanistic "allowed" is exactly the semantic gap this paper names. Also: if a hazardous trajectory's TD-error is not high, PER will not raise its sampling probability — but that is no rebuttal of the admission layer: the hazard is then merely "unnoticed," not "quarantined and retained by a policy layer." P2's point is not "not learned," but "flagged, retained, analyzable."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So this paper does not replace the optimizer or the collaboration layer; it argues for an explicit data plane between them. Structure: contributions → P1–P4 and their logical interdependence (§3) → neighbors (§3.1) → interface and predicate (§4) → hypotheses (§5) → falsification protocol (§6) → objections (§7) → conclusion.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Contributions and non-claims
&lt;/h2&gt;

&lt;p&gt;This is a technical position paper, not a methods paper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribution one: restating the problem.&lt;/strong&gt; "After trajectories are generated, who may materialize, at what granularity, and when θ may update" is promoted to an independent system layer. If the name can be fully absorbed by existing terms, the name &lt;strong&gt;should be retired&lt;/strong&gt;. Even retired, P1–P4 and the §6 protocol remain independently testable as a &lt;strong&gt;system interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribution two: the proposed admission policy P1–P4.&lt;/strong&gt; A minimal &lt;em&gt;set of design differences&lt;/em&gt; relative to PER/deletion-style filtering, with a logical-interdependence argument (§3.2). The novelty is pressed onto four switchable constraints, not a fingerprint formula. &lt;strong&gt;No claim&lt;/strong&gt; that empirical minimality has been proven by causal ablation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribution three: a falsifiable protocol.&lt;/strong&gt; A/B (plus a PER arm) and five preregistered failure conditions; condition 5 can fail the strong-form configuration on the current proxy family (§6).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not claimed:&lt;/strong&gt; theoretical guarantees; proven causal irreducibility; collaboration products as an RL baseline; optimality of placeholder parameters; strong-form coverage of black-box APIs; LoRA/cloud fine-tuning as main results; the appendix as proven method results; the §6.4 gate as validation success or "must be a first-class module."&lt;/p&gt;


&lt;h2&gt;
  
  
  3. The proposed admission policy: why it is not "renamed PER/filtering"
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Terms (materialization vs deep read).&lt;/strong&gt; In this paper, &lt;em&gt;materialization&lt;/em&gt; means turning a trajectory from streaming state into an inspectable, persisted object; &lt;em&gt;deep read&lt;/em&gt; means running costly analysis on materialized trajectories (full unrolling, replay, value estimation). In most implementations both fall under "admission cost," but they are logically separable — one can materialize then deep-read, or deep-read in streaming state and discard. For brevity, budget and metric contexts say "materialization cost" for both; when distinguished, materialization is storage-side and deep read is compute-side. &lt;code&gt;D_read&lt;/code&gt; is the set eligible for materialization/deep-read — not the admitted-to-update set.&lt;/p&gt;

&lt;p&gt;If the critic asks what remains once the name is removed, the answer is four &lt;strong&gt;design constraints&lt;/strong&gt;. Only when enforced &lt;strong&gt;together as a policy&lt;/strong&gt; is "experience admission control" worth using; any one missing in the long run retires the name. They are a &lt;strong&gt;proposed admission policy&lt;/strong&gt;, not a published scientific finding.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Constraint&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;PER usually?&lt;/th&gt;
&lt;th&gt;Deletion-style safety filtering usually?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;P1 materialize-off by default&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full materialization off by default; explicit authorization and quota required&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No (judgments typically made on already-materialized trajectories)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;P2 quarantine ≠ delete&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-risk trajectories can be barred from &lt;code&gt;D_adm&lt;/code&gt; while keeping analysis value&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Usually no (intercept or discard)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;P3 materialization ≠ admission&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unrolled/inspected ≠ permission to update θ&lt;/td&gt;
&lt;td&gt;No (sampled ⇒ learned)&lt;/td&gt;
&lt;td&gt;Partial; observation and update rarely separated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;P4 visible-set proper containment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When hot is nonempty, &lt;code&gt;D_adm ⊊ D_all&lt;/code&gt; — not "all learnable, merely reweighted"&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No (shrinks actions; does not define the training visible set)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;P4 boundary.&lt;/strong&gt; When hot is empty the sets may satisfy &lt;code&gt;D_adm = D_all&lt;/code&gt;, but the strong form still requires P1/P3, and true containment must be restored once a hot-hazard appears. A long-run state of "hot empty + everything learnable by default" = the admission layer is not implemented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why P1 and P3 are not merged.&lt;/strong&gt; They are logically separable: one can materialize without admitting; "admit without materializing" is the dangerous direction. &lt;strong&gt;The strong form forbids the latter as a default path:&lt;/strong&gt; summaries may at most serve routing/promotion proposals; entering &lt;code&gt;D_adm&lt;/code&gt; requires independent validation (§4). The names must stay separate, otherwise per-item ablation is impossible (§8).&lt;/p&gt;

&lt;p&gt;PER can rank the warm tier; shields can flag hazards — neither automatically yields the whole admission policy. Calling TD-error reweighting "admission" is naming inflation.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.1 Neighbors: why it is also not "renamed LLM data curation"
&lt;/h3&gt;

&lt;p&gt;Preference filtering [10], RLAIF [11], RAFT-style rejection sampling [12], and alignment-pipeline filters [13] in LLM post-training optimize quality and labeling cost before the batch, usually with a default of: kept ⇒ update θ; dropped ⇒ out of training.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Neighbor&lt;/th&gt;
&lt;th&gt;Usually optimizes&lt;/th&gt;
&lt;th&gt;Still missing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Filtering [10]&lt;/td&gt;
&lt;td&gt;Denoising, preference-data quality&lt;/td&gt;
&lt;td&gt;Little separation of inspectable/updatable; discard ≠ quarantine-with-retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RLAIF [11]&lt;/td&gt;
&lt;td&gt;Scaling labels via AI feedback&lt;/td&gt;
&lt;td&gt;No policy for the training visible set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAFT-style [12]&lt;/td&gt;
&lt;td&gt;Train only on high-score completions&lt;/td&gt;
&lt;td&gt;Binary keep/delete; &lt;strong&gt;high score ≠ low risk&lt;/strong&gt;; no quarantine track&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alignment filter [13]&lt;/td&gt;
&lt;td&gt;Engineering data cleanliness&lt;/td&gt;
&lt;td&gt;No multi-worker materialization budget, no hot→θ hard constraint&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neighbors are implementation components; not the same object. Multi-phase exploration (e.g., First Return, Then Explore [4]) shows staged policies like "return first, then explore" work in long-horizon settings, but its object is the &lt;strong&gt;exploration schedule and state coverage&lt;/strong&gt; — it defines neither materialization budgets, nor a quarantine-with-retention track, nor an enforced proper containment of &lt;code&gt;D_adm&lt;/code&gt; relative to &lt;code&gt;D_all&lt;/code&gt;. Orthogonal to this admission policy, not a substitute.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.2 Logical interdependence (counterfactuals): why the four come together
&lt;/h3&gt;

&lt;p&gt;The following argues &lt;strong&gt;logical minimality&lt;/strong&gt;, not causal ablation. Whether they are empirically irreducible remains §8.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Counterfactual&lt;/th&gt;
&lt;th&gt;The policy degrades into&lt;/th&gt;
&lt;th&gt;Therefore&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Drop P1, keep P2–P4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The materialization budget vanishes → warm/hot partitioning loses budget meaning, leaving a labeling layer of "flagged or not"; behavior approaches an unbudgeted hybrid cache (isolation tags may remain)&lt;/td&gt;
&lt;td&gt;Without the budget constraint the cost differential vs the passive pool is hard to sustain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Drop P2, keep the rest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High risk can only be deleted or learned as ordinary samples → degrades into delete-filter / no analysis track (near shielding + discard)&lt;/td&gt;
&lt;td&gt;Without P2, "quarantine utilization" disappears&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Drop P3, keep the rest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;D_read ≡ D_adm&lt;/code&gt;: seen ⇒ learned → behavior approaches PER / the passive pool&lt;/td&gt;
&lt;td&gt;Without P3, back to sampling-is-learning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Drop P4, keep the rest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The nominal three tiers and P1–P3 may remain, but when hot is nonempty &lt;code&gt;D_adm ⊊ D_all&lt;/code&gt; is &lt;strong&gt;no longer forced&lt;/strong&gt;: a hybrid cache with budgets/quarantine/materialization–update separation yet no enforced visible-set containment — &lt;strong&gt;still distinct from PER&lt;/strong&gt;, but it has lost the visible-set-level policy difference&lt;/td&gt;
&lt;td&gt;Without P4, proper containment cannot be enforced; &lt;strong&gt;not&lt;/strong&gt; a return to pure PER&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why all four together (design level):&lt;/strong&gt; each blocks one collapse mode — "default materialization / delete-or-learn / seen-is-learned / no visible-set hard constraint." With any one missing, the remaining clauses cannot alone support the &lt;strong&gt;complete&lt;/strong&gt; admission-layer claim. P1–P4 as a &lt;strong&gt;proposed list&lt;/strong&gt; should be proposed and tested together; dropping P4 is &lt;strong&gt;not&lt;/strong&gt; a return to pure PER, but it abandons the full visible-set-policy spec. It does &lt;strong&gt;not&lt;/strong&gt; mean an intervention experiment has proven them the world's unique minimal set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known limitation (empirical):&lt;/strong&gt; no causal ablation yet of which constraint drives the behavioral difference vs PER. An aggregate A/B/PER win does not substitute for per-item mechanism validation (§8). Logical interdependence does not fill that gap; it only fends off the "four random engineering intuitions" accusation.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Minimal interface and the admission predicate
&lt;/h2&gt;

&lt;p&gt;No full algorithm or formal system. Fix the &lt;strong&gt;interface + minimal predicate constraints&lt;/strong&gt; so the objects are discussable and implementable.&lt;/p&gt;

&lt;p&gt;The dataflow:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel x-arrow"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight x-arrow-pad"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;ϕ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="svg-align"&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="hide-tail"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel x-arrow"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight x-arrow-pad"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;r&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="svg-align"&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="hide-tail"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathcal"&gt;B&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel x-arrow"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight x-arrow-pad"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathrm mtight"&gt;adm&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="svg-align"&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="hide-tail"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;D&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathrm mtight"&gt;adm&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel x-arrow"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight x-arrow-pad"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathcal mtight"&gt;A&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="svg-align"&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="hide-tail"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;adm&lt;/code&gt; is the admission mapping constrained by P1–P4; the optional review &lt;code&gt;gate&lt;/code&gt; is an implementation component only.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;φ:&lt;/strong&gt; cheap, streaming, local (C3 placeholder, replaceable; not counted as a contribution).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;r(x_t) ∈ {archive, warm, hot}&lt;/code&gt;:&lt;/strong&gt; routes materialization / deep-read priority — not "who matters more," and &lt;strong&gt;not&lt;/strong&gt; by itself the update ban. Update eligibility is decided only by the admission predicate (§4.1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ℓ(τ) ∈ {promising, hazard}&lt;/code&gt;:&lt;/strong&gt; assigned on the quarantine / analysis track. &lt;strong&gt;Before any write to θ&lt;/strong&gt;, a still-&lt;code&gt;hot&lt;/code&gt; trajectory must already carry an assigned &lt;code&gt;ℓ&lt;/code&gt;; otherwise &lt;code&gt;HotHazard&lt;/code&gt; is unevaluable and the trajectory stays outside &lt;code&gt;D_adm&lt;/code&gt;. After labeling: &lt;code&gt;hot ∧ hazard&lt;/code&gt; never enters &lt;code&gt;D_adm&lt;/code&gt;; &lt;code&gt;hot ∧ promising&lt;/code&gt; may enter only if &lt;code&gt;Validated&lt;/code&gt; and &lt;code&gt;InBudget&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sets:&lt;/strong&gt; &lt;code&gt;D_read&lt;/code&gt; and &lt;code&gt;D_adm&lt;/code&gt; are policy-separated; &lt;code&gt;D_restricted&lt;/code&gt; excludes hot-hazard; when hot is nonempty, &lt;code&gt;D_adm ⊊ D_all&lt;/code&gt;, and always &lt;code&gt;D_adm ⊆ D_restricted&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.1 The minimal admission predicate
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;∈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;D&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathrm mtight"&gt;adm&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⟺&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathrm"&gt;Validated&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;∧&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;¬&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathrm"&gt;HotHazard&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;∧&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathrm"&gt;InBudget&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;where:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathrm"&gt;HotHazard&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⟺&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;&lt;span class="delimsizing size1"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;r&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathrm"&gt;hot&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;∧&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;ℓ&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;τ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord texttt"&gt;hazard&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="delimsizing size1"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;Validated&lt;/code&gt; is promotion validation independent of the routing score; &lt;code&gt;InBudget&lt;/code&gt; encodes the &lt;strong&gt;materialization quota&lt;/strong&gt; (P1) and capacity caps on the promotion channel (implementation detail; works with the P3/P4 gates, not owned by P1 alone).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interaction with 𝒜:&lt;/strong&gt; at any update step t, the optimizer's batch satisfies &lt;code&gt;B_t ⊆ D_adm&lt;/code&gt;. 𝒜 &lt;strong&gt;need not&lt;/strong&gt; internalize admission semantics; it only needs its input set constrained by the admission layer. If &lt;code&gt;B_t ⊄ D_adm&lt;/code&gt;, that is a &lt;strong&gt;contract breach&lt;/strong&gt;; if the breaching batch contains a hot-hazard, §6.3 condition 4 fires as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Minimal implementation contract
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;No hot-hazard enters a batch that updates θ.&lt;/li&gt;
&lt;li&gt;Materialization happens in &lt;code&gt;D_read&lt;/code&gt;; writes to θ go only through &lt;code&gt;D_adm&lt;/code&gt; (P3).&lt;/li&gt;
&lt;li&gt;Promotion requires validation independent of the routing score.&lt;/li&gt;
&lt;li&gt;Archive is not materialized by default; warm materialization is budgeted (P1).&lt;/li&gt;
&lt;li&gt;An optional gate must not enlarge the allowed sets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Strong-form assumption:&lt;/strong&gt; workers expose at least one observable signal; otherwise this is the black-box degradation, outside the claim. "Admit without materializing" is forbidden as a default path.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Testable hypotheses
&lt;/h2&gt;

&lt;p&gt;These form the operational version of C2. &lt;strong&gt;The main protocol (§6) tests H1/H2/H4 plus P2's minimal execution integrity (condition 4: quarantine barred from updates + a nonempty quarantine must be read/used for peripheral analysis). H3 tests the "measurable peripheral value" magnitude of quarantine-with-retention; it is exploratory and does not enter §6.4.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H1 (primary):&lt;/strong&gt; coarse routing + selective materialization lowers materialized volume relative to the passive pool while maintaining task performance.&lt;br&gt;
&lt;strong&gt;H2 (primary):&lt;/strong&gt; the three tiers, relative to binary filtering, retain analyzable anomalies without increasing base-policy contamination.&lt;br&gt;
&lt;strong&gt;H3 (exploratory):&lt;/strong&gt; quarantine-with-retention, versus immediate discard, yields &lt;strong&gt;measurable positive value&lt;/strong&gt; on offline monitors/discriminators — condition 4 already forbids "quarantined but never read"; H3 further asks whether reading helps, and is &lt;strong&gt;not a §6.4 requirement&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;H4 (primary):&lt;/strong&gt; "low frequency" means &lt;strong&gt;limited update-contact frequency with the base policy and visible-set size&lt;/strong&gt; — not learning rate / SGD step count; constrained updates are more stable than default-open ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 H ↔ P
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hypothesis&lt;/th&gt;
&lt;th&gt;Mainly depends on&lt;/th&gt;
&lt;th&gt;On failure, first suspect&lt;/th&gt;
&lt;th&gt;Protocol role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;H1&lt;/td&gt;
&lt;td&gt;P1&lt;/td&gt;
&lt;td&gt;Condition 5 or condition 1&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;H2&lt;/td&gt;
&lt;td&gt;P2+P4&lt;/td&gt;
&lt;td&gt;Degradation to binary keep/delete; hot still entering updates&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;H3&lt;/td&gt;
&lt;td&gt;P2 (value magnitude)&lt;/td&gt;
&lt;td&gt;Read but no peripheral gain&lt;/td&gt;
&lt;td&gt;Exploratory (§8); full enforcement via condition 4(b)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;H4&lt;/td&gt;
&lt;td&gt;P3+P4&lt;/td&gt;
&lt;td&gt;Materialize ⇒ write; update-contact frequency ≈ passive pool&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;§6 tests the aggregate effect of the primary hypotheses; H3 and per-P ablations belong to §8.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Preregistered falsification protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Comparison
&lt;/h3&gt;

&lt;p&gt;Same 𝒜, task, worker class:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arm&lt;/th&gt;
&lt;th&gt;Dataflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Passive pool: materializable/replay-eligible by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Admission: P1–P4 + §4 contract/predicates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P&lt;/td&gt;
&lt;td&gt;PER on the same buffer — sampling weights, not admission semantics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  6.2 Core metrics (minimal operational definitions)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Effective materialization ratio&lt;/td&gt;
&lt;td&gt;materialized/unrolled volume ÷ total generated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wall-clock/FLOPs&lt;/td&gt;
&lt;td&gt;cost to reach the segment-return threshold&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task return&lt;/td&gt;
&lt;td&gt;same protocol as A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hazard penetration rate&lt;/td&gt;
&lt;td&gt;share of hazard/hot-hazard in update batches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Materialization gain&lt;/td&gt;
&lt;td&gt;on preregistered held-out probes, return improvement or loss drop after vs before materialization (fix one). &lt;strong&gt;Allowed:&lt;/strong&gt; averaging/median over preregistered trajectory subsets, or preregistered smoothing (e.g., sliding window) to reduce single-trajectory noise; the aggregation is fixed in the experiment plan and never changed post hoc. Serves as a condition-5 label only; not a success criterion by itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signal–gain ρ&lt;/td&gt;
&lt;td&gt;Spearman between calibrated routing score and (aggregated/smoothed) materialization gain&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  6.3 Failure conditions
&lt;/h3&gt;

&lt;p&gt;Window K ≥ 3 segments (fixed in the plan). &lt;strong&gt;Any one firing&lt;/strong&gt; rejects the position in that setting.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Warm-tier collapse&lt;/strong&gt; — warm &lt;strong&gt;traffic&lt;/strong&gt; share ≥ 90% (or archive+hot combined &amp;lt; 10%), and effective-materialization-ratio improvement vs A &amp;lt; 5%. Warm traffic share = trajectories routed to warm in the window (or transitions; measurement fixed at preregistration) ÷ total generated in the same window.
&lt;em&gt;Measurement:&lt;/em&gt; traffic = routing counts; effective materialization ratio = actual cost. They need not agree. Condition 1 is a conjunction: traffic piling into warm &lt;strong&gt;and&lt;/strong&gt; materialization cost not substantially reduced. High traffic with a clear cost drop does &lt;strong&gt;not&lt;/strong&gt; fire.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No budget improvement&lt;/strong&gt; — materialization-ratio improvement &amp;lt; 10% and wall-clock/FLOPs improvement &amp;lt; 5% (default &lt;strong&gt;AND&lt;/strong&gt;; division of labor with condition 1: 1 catches "nominal tiers + no cost reduction," 2 catches "no substantive budget gain vs A overall").
&lt;em&gt;Grey zone:&lt;/em&gt; materialization-ratio improvement ∈ [5%, 10%) (or &amp;lt; 5% without firing condition 1) with wall-clock ≥ 5% — conditions 1–2 both go unfired, but §6.4 is unmet (which requires ≥ 10%) — &lt;strong&gt;no scale-up claim&lt;/strong&gt;, and no threshold changes post hoc. Any alternative joint criterion (weighted OR, "wall-clock compensates ratio," etc.) must be fixed explicitly at preregistration; otherwise condition 2 runs as AND.&lt;/li&gt;
&lt;li&gt;In ≥ ⌈2K/3⌉ of K segments, return is significantly below A (preregistered α/MID).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard (P2 integrity):&lt;/strong&gt; (a) any hot-hazard enters &lt;code&gt;D_adm&lt;/code&gt; and updates θ; &lt;strong&gt;or&lt;/strong&gt; (b) within the evaluation window the quarantine region (hot, or a preregistered quarantine set) is &lt;strong&gt;nonempty&lt;/strong&gt; but its trajectories are &lt;strong&gt;never&lt;/strong&gt; read/deep-read and &lt;strong&gt;never&lt;/strong&gt; used for any preregistered peripheral analysis (monitoring, discriminators, audit logs, etc.) — "quarantine-to-forget": P2 execution incomplete, hard failure. If hot is empty, (b) does not apply.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard (proxy–gain test)&lt;/strong&gt; — tests whether the current preregistered proxy family still carries learnable information (see §7.2), in three clauses; &lt;strong&gt;any clause firing fails condition 5&lt;/strong&gt; (all three must be run; do not report only the passing ones):

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Correlation:&lt;/strong&gt; one-sided test of the calibrated Spearman ρ (routing score vs materialization gain), alternative ρ &amp;gt; 0; preregistered α (e.g., 0.05), never changed post hoc. Nonsignificant → fires.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random baseline:&lt;/strong&gt; i.i.d. uniform archive/non-archive labels at the same archive marginal frequency; if the router's F1/accuracy on "is-archive" is within δ of that baseline (δ preregistered) → indistinguishable from random → fires.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy-family boundary:&lt;/strong&gt; "changing family" = an &lt;strong&gt;architectural&lt;/strong&gt; change of the score function (e.g., entropy → prediction error, or fixed features → learnable projection). Tuning thresholds/normalization/windows within the same function = &lt;strong&gt;same configuration&lt;/strong&gt;; the test must be rerun; renaming one's way around a rejection is not allowed. After failure, at most weak post-hoc filtering remains, never conflated with the strong form; a new family requires fresh preregistration and inherits nothing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6.4 Scale-up gate (≠ validation success)
&lt;/h3&gt;

&lt;p&gt;Relative to A: effective-materialization-ratio improvement ≥ 10%; condition 3 unfired; conditions 4–5 unfired (including 4(b): a nonempty quarantine must be read/used for peripheral analysis).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reading:&lt;/strong&gt; this only means &lt;strong&gt;no failure condition fired&lt;/strong&gt;, licensing larger experiments. It does &lt;strong&gt;not&lt;/strong&gt; mean validation success, is &lt;strong&gt;not&lt;/strong&gt; a "weak success," and does &lt;strong&gt;not&lt;/strong&gt; by itself imply "must become a first-class module." With small samples or high variance it must not be read as evidence of effect. H3's "measurable positive value" still awaits the scale-up stage or §8; the gate does not assert it alone.&lt;br&gt;
&lt;strong&gt;Design recommendation (normative, not a protocol conclusion):&lt;/strong&gt; if the scaled experiments still pass, &lt;em&gt;then&lt;/em&gt; recommend making the admission policy a first-class module of the training pipeline, rather than the default passive pool/PER.&lt;/p&gt;

&lt;p&gt;(Optional observation: materialization-ratio improvement ≥ 10% with return not below A's preregistered MID — still not promoted to a primary claim.)&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Objections
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 "This is just renamed replay/filtering"
&lt;/h3&gt;

&lt;p&gt;Pressed to the P1–P4 of §3 and the logical interdependence of §3.2. If existing terms can fully absorb it, retire the name. The interface remains testable per §2/§6. The empirical causal decomposition is still missing (§8).&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2 "A cheap signal may not correlate with learnable value"
&lt;/h3&gt;

&lt;p&gt;This is the deepest statistical fragility of the strong form. ICM/RND [7,8] show uncertainty signals have prior correlation with learning state in short-horizon settings; whether &lt;strong&gt;some preregistered proxy family&lt;/strong&gt; remains correlated in long-horizon agentic settings is open — condition 5 exists precisely to test it. If the correlation cannot be established, what fails is &lt;strong&gt;the strong-form configuration on that proxy family&lt;/strong&gt; — not a threshold tuned for another chance. Only an &lt;strong&gt;architectural&lt;/strong&gt; proxy change (see §6.3) may be preregistered as a new family and rerun; tuning within the same function is not a new family. At most, weak post-hoc filtering survives.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.3 "No theory, no hard enough experiments"
&lt;/h3&gt;

&lt;p&gt;The main text defends: a proposed policy + logical interdependence + a falsifiable protocol. The appendix is not a third layer. If ablations/LLM main results are demanded → concede §8, no number inflation.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.4 "White-box is too narrow for the breadth of the motivation"
&lt;/h3&gt;

&lt;p&gt;The narrowing is accepted: title and abstract are limited to white-box observability. Cloud black-box APIs are real mainstream practice — and &lt;strong&gt;another paper's weak-form problem&lt;/strong&gt;; this one does not stretch to cover them.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.5 Applicability boundary (informal)
&lt;/h3&gt;

&lt;p&gt;This protocol targets long-horizon RL settings with high materialization/deep-read costs and heterogeneous workers. If trajectories are short (say mean length L &amp;lt; 100), single-worker, with negligible materialization cost, the admission layer's extra system complexity may exceed its benefit; a passive pool or PER remains a reasonable default. Even when an experiment passes §6, a designer may still decline to ship for engineering-cost reasons — a pass only says "the hypothesis was not falsified in that setting"; it mandates no wholesale replacement. The claim of this paper: in suitable settings, treat the admission layer as an &lt;strong&gt;explicit design dimension&lt;/strong&gt;, not a universal default.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Future work
&lt;/h2&gt;

&lt;p&gt;(1) Causal ablation of P1–P4 (empirical minimality after logical interdependence). (2) White-box open-weight multi-seed A/B/PER. (3) Learnable routing aligned with condition 5. (4) H3: on top of condition 4(b)'s guarantee that "a nonempty quarantine must be used," add independent peripheral &lt;strong&gt;value&lt;/strong&gt; metrics and controls, then decide whether to fold it into the scale-up gate. (5) Whether the black-box weak form retains part of the policy semantics — a separate paper, not mixed into the strong form.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In white-box observable multi-worker asynchronous RL there is a frequently ignored dataflow-organization problem between the optimizer and the collaboration interface. This paper names it experience admission control and proposes P1–P4 as a &lt;strong&gt;proposed admission policy&lt;/strong&gt; (with logical interdependence and a falsification protocol). Whether it holds empirically is an open question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testable verdict (layered):&lt;/strong&gt; fix 𝒜, vary only the data plane. Meeting the §6.4 scale-up gate → larger experiments allowed, &lt;strong&gt;not&lt;/strong&gt; validation success and &lt;strong&gt;not&lt;/strong&gt;, by itself, "must become a first-class module." If it still passes after scale-up, then, as a &lt;strong&gt;design recommendation&lt;/strong&gt;, make the admission policy a first-class module of the training pipeline; otherwise withdraw that configuration's strong-form claim.&lt;/p&gt;

&lt;p&gt;What is sought is not "proven correct," but a publicly testable, falsifiable question: &lt;strong&gt;on observable workers, should experience enter the base update path in a layered, isolated, low-frequency way?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Hou, Z., Li, Y., Tang, J., Dong, Y. &lt;em&gt;Single-Rollout Asynchronous Optimization for Agentic Reinforcement Learning&lt;/em&gt;. &lt;a href="https://arxiv.org/abs/2607.07508" rel="noopener noreferrer"&gt;arXiv:2607.07508&lt;/a&gt;, 2026.&lt;/li&gt;
&lt;li&gt;Shao, Z., Wang, P., Zhu, Q., et al. &lt;em&gt;DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models&lt;/em&gt; (GRPO). &lt;a href="https://arxiv.org/abs/2402.03300" rel="noopener noreferrer"&gt;arXiv:2402.03300&lt;/a&gt;, 2024.&lt;/li&gt;
&lt;li&gt;Schaul, T., Quan, J., Antonoglou, I., Silver, D. &lt;em&gt;Prioritized Experience Replay&lt;/em&gt;. ICLR, 2016.&lt;/li&gt;
&lt;li&gt;Ecoffet, A., et al. &lt;em&gt;First Return, Then Explore&lt;/em&gt;. Nature, 2021.&lt;/li&gt;
&lt;li&gt;Espeholt, L., et al. &lt;em&gt;IMPALA: Scalable Distributed Deep-RL with Importance Weighted Actor-Learner Architectures&lt;/em&gt;. ICML, 2018.&lt;/li&gt;
&lt;li&gt;Kumar, A., Zhou, A., Tucker, G., Levine, S. &lt;em&gt;Conservative Q-Learning for Offline Reinforcement Learning&lt;/em&gt;. NeurIPS, 2020.&lt;/li&gt;
&lt;li&gt;Pathak, D., Agrawal, P., Efros, A., Darrell, T. &lt;em&gt;Curiosity-driven Exploration by Self-supervised Prediction&lt;/em&gt;. ICML, 2017.&lt;/li&gt;
&lt;li&gt;Burda, Y., Edwards, H., Storkey, A., Klimov, A. &lt;em&gt;Exploration by Random Network Distillation&lt;/em&gt;. ICLR, 2019.&lt;/li&gt;
&lt;li&gt;Alshiekh, M., et al. &lt;em&gt;Safe Reinforcement Learning via Shielding&lt;/em&gt;. AAAI, 2018.&lt;/li&gt;
&lt;li&gt;Hu, Y., et al. &lt;em&gt;Towards Comprehensive Preference Data Collection for Reward Modeling&lt;/em&gt;. &lt;a href="https://arxiv.org/abs/2406.16486" rel="noopener noreferrer"&gt;arXiv:2406.16486&lt;/a&gt;, 2024.&lt;/li&gt;
&lt;li&gt;Lee, H., et al. &lt;em&gt;RLAIF vs. RLHF&lt;/em&gt;. &lt;a href="https://arxiv.org/abs/2309.00267" rel="noopener noreferrer"&gt;arXiv:2309.00267&lt;/a&gt;, 2023.&lt;/li&gt;
&lt;li&gt;Dong, H., et al. &lt;em&gt;RAFT: Reward rAnked FineTuning&lt;/em&gt;. TMLR, 2023.&lt;/li&gt;
&lt;li&gt;Wang, Z., et al. &lt;em&gt;Reinforcement Learning for LLM Post-Training: A Survey&lt;/em&gt; (v1 originally titled &lt;em&gt;A Comprehensive Survey of LLM Alignment Techniques&lt;/em&gt;). &lt;a href="https://arxiv.org/abs/2407.16216" rel="noopener noreferrer"&gt;arXiv:2407.16216&lt;/a&gt;, 2024.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;Previous in this series: &lt;a href="https://dev.to/zxpmail/the-mirror-cannot-reflect-thought-ig9"&gt;The Mirror Cannot Reflect Thought&lt;/a&gt; · &lt;a href="https://dev.to/zxpmail/from-show-me-your-code-to-show-me-your-idea-30kk"&gt;From "show me your code" to "show me your idea"&lt;/a&gt; · &lt;a href="https://dev.to/zxpmail/judging-fatigue-from-verifying-ai-to-verifying-myself-4m0p"&gt;Judging Fatigue: From Verifying AI to Verifying Myself&lt;/a&gt; · &lt;a href="https://dev.to/zxpmail/the-boundary-of-the-harness-29cj"&gt;The Boundary of the Harness&lt;/a&gt; · &lt;a href="https://dev.to/zxpmail/a-reviewer-nailed-me-in-six-places-3m95"&gt;A Reviewer Nailed Me in Six Places&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reinforcementlearning</category>
      <category>machinelearning</category>
      <category>aiagents</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
