Three things the prompt side said more than once, and the first of them was
not only repetition: the two copies disagreed.
WHAT IS INTERACTIVE WAS DECLARED TWICE, IN TWO LANGUAGES. clean.py held
nineteen roles for the sieve; the snapshot's selector held seven, typed by hand
inside a JavaScript string in another module, where nothing could compare them.
Measured on a page of ARIA controls, driven through the real server: a
role=combobox and a role=slider with no tabindex came back from
browser_read_html and were absent from browser_snapshot, which is the tool the
instructions name as the way to find something to click. Seven controls in all,
invisible to the rung the ladder starts on, while the sieve saw every one.
The snapshot now asks the page for the selector clean.py builds, so there is
one list. The one difference the two need is NAMED instead of being left to a
second list to imply: roles whose members come in hundreds - option, gridcell -
are kept by the sieve and left out of the inventory, which is the measurement
the snapshot's own docstring already carried about a country select with two
hundred options. Before and after on the same engine: 8 elements to 15, seven
gained, none lost, and a thirty-item listbox still contributes one row.
The selector is joined by concatenation and not substituted into the script.
That block holds 12 literal percent signs, and a placeholder searched for
inside code is found inside the caller's code too - which is the defect fixed
one layer down yesterday.
THE SAME SENTENCE ABOUT browser CLOSED THIRTEEN DESCRIPTIONS, word for word.
It is on the parameter now, said once. It also spent the wrong budget: a
description is cut at 1024 characters before the model reads it and
browser_open sat at 1021, three characters from losing the sentence that says
who closes support, which is the defect its own gate exists for. It is 1004
now, and the room went to two rules that had been cut for space and left in a
comment no model would ever read.
AND THE FIRST VERSION OF THAT MOVE WAS A LOSS, which only a measurement
said. A schema travels with its tool every turn exactly as a description does,
so thirteen copies in the schemas is the same duplication moved, and the
four-sentence version made it dearer: descriptions -256 tokens, schemas +900,
complete definitions +617, sixteen percent MORE per turn for a change whose
point was to spend less. The parameter carries one line now and the whole
definition is -13 tokens, which is to say the same cost. The saving was never
the point; not saying it thirteen times is.
THE RULE ABOUT OPENING FIRST WAS IN BOTH TEXTS THAT MAKE ONE MESSAGE. The
loop's prompt opened with it and the server's instructions say it in their
first paragraph, glued on a few lines below: the model read it twice. It
belongs to the server, because it is a fact about the tools and a standalone
client that never sees the loop's prompt still has to be told it. A gate holds
that the home is not empty, which is the half that matters when a sentence
moves.
A draft also made an empty instructions string append a warning for the model.
It was dropped: the link launches this very server, so arriving with nothing
means the handshake failed, and a sentence in the prompt helps nobody in that
state. Four tests said so before I did.
AND THE FIGURE MOVED IN FOURTEEN PUBLISHED PAGES. 9,097 characters became
8,105, and the token counts with it, across 21 occurrences that a content gate
checks in only one of its four numbers. Of the fourteen pages, TWO published
the token figure with no character figure beside it, so on those two the
neighbour the gate relies on protected nothing. Both were given the figure they
were missing, and the gate now holds the arrangement rather than hoping for it,
which needs no tokenizer: it checks that the number it CAN verify is present.
Suite 632 green. Eleven known-bad inputs, eleven killed, plus the gate's own
selftest at 18 mutations and 13 clean cases. One of the eleven survived the
first run and the gate was genuinely blind: it asked whether anything in the
excluded set was inventoried, which a mutation satisfies by moving the role
into the other set. The two names are written out now. Another was killed by
the parser rather than by the gate, which is not a kill; rewritten as valid
Python, the gate kills it.