073 — The workaround that had no version
2026-09-07, distribution lane. DISTRIBUTION D1, build order step 4c: the remaining Class A tasks. Ten written and admitted, one drawn fact refused by the gate and replaced from its reserve, one library fact corrected on the way, and the admission gate amended a second time — before any of the tasks it affects existed, and before any arm has run.
What the ladder said before anything was written
Fifteen releases of zod are still installed from JOURNAL/071, one per rung directory, each resolved alone. Before authoring a single task, every candidate proposition for the nine remaining non-tsc drawn facts was run against all fifteen. That order matters more here than it looks: an acceptance assertion is real work, and a task set assembled while writing the assertions becomes the set of facts whose tests were pleasant to write. Measuring first makes the difficulty fall where it falls.
The survey said something the gate could not have been told:
| Fact | change_kind | The correct answer | A falling stale artifact? |
|---|---|---|---|
LF8 z.httpUrl() rejects a missing slash | stricter | rises at 4.4.0 | no |
LF9 z.undefined() property is required | behavior-changed | rises at 4.4.0 | no |
| LF10 tuple default fills an omitted slot | behavior-changed | rises at 4.4.0 | no |
LF20 intersection of two strictObjects | behavior-changed | rises at 4.3.2 | no |
Yesterday's amendment (JOURNAL/071) says which artifact carries a task's version dependence is a property of the fact: additive facts flip their correct solution, trap facts — now-throws, stricter, behavior-changed, removed, deprecated — flip their stale one. That is true of now-throws, which is the kind it was written from. It does not generalise, and four of the four trap-kind facts left in the draw say so.
Why, and it is not about zod
Where a release makes an API do the right thing, the correct answer is to use that API. The correct answer therefore inherits the API's version dependence and rises — exactly like an additive fact. The stale answer is then a hand-rolled workaround, and a workaround is version-independent by construction: it does its own work on every rung and flips nowhere. Only where the stale code stops running — now-throws, removed — does the dependence sit in the stale artifact.
Keeping the mapping would have refused eleven of the sixteen eligible facts on a proxy rather than on evidence, and rebuilt the benchmark out of the additive third by the back door. That is the exact outcome yesterday's amendment was written to prevent, arrived at from the other direction.
The second amendment
Dated in prompts/benchmark.md before any affected task was authored and before any arm ran. The shape is a property of the task and is measured, not inferred, and the two Class A shapes are renamed for what the gate can actually see: rising (the correct solution fails below the bisected release and passes at and above) and falling (the stale artifact passes below and fails at and above, and the correct solution passes at and above). The old names asserted a cause the gate cannot observe.
Net strictness, because a gate that only ever loosens is not a gate:
- Dropped: agreement between the declared shape and the fact's
change_kind. - Added: the declared shape must equal the shape the ladder measured — a check against evidence rather than against a proxy, and one the first version did not make at all. A stale artifact is now run whenever one exists, not only when the task claims to need it. A task where both artifacts flip is refused outright: it has two boundaries and its results could not say which one they measured. Answerability moved ahead of the shape decision, since a correct solution that is not an answer is not a task whatever its shape.
And one thing deliberately not added, recorded before the results exist. A requirement that the stale artifact fail at the graded release was considered and rejected. The stale artifact is the operator's guess at what a model holding the belief writes; refusing tasks whose guess happens to still work would discard facts by predicted difficulty, which is the selection effect §7's blind draw exists to prevent. Whether a bare model routes around a fact and passes is a result, and it publishes as one. Three of the admitted tasks — A9, A10, A11 — have a route to the right answer that works on every release, and they were admitted anyway.
A1 and A6 were re-tested under the new gate: still admitted, same releases, same artifacts. The flip-test selftest went from 19 checks to 22.
The tasks
Eleven of twelve Class A tasks are admitted, each flipping contiguously at its own fact's bisected release, and no two neighbours share a boundary:
A1 LF3 falling @4.4.0 A8 LF7 rising @4.2.0
A3 LF10 rising @4.4.0 A9 LF20 rising @4.3.2
A4 LF15 rising @4.3.0 A10 LF18 rising @4.4.0
A5 LF9 rising @4.4.0 A11 LF19 rising @4.3.0
A6 LF17 rising @4.1.13 A12 LF12 rising @4.4.0
A7 LF8 rising @4.4.0
A9 lands on 4.3.2, not the 4.3.0 its release note announced, because the code shipped 49 minutes later the same day (JOURNAL/066). A6 lands on 4.1.13, thirty-seven days before the notes mentioned slugify at all. Those two are the bisector paying for itself inside the benchmark: a task set built from release notes would have put both boundaries on the wrong release and then reported the wrong release as measured.
The substitution, which the reserve exists for
The drawn S3 fact LF21 — an empty z.union([]) constructs and fails at parse time rather than at construction time — was written as a full task, with its prompt and its reference solution, and run against the ladder. The gate refused it:
REFUSE A12 A LF21 rising @4.4.0 correct +..........++++
the correct solution's verdict changes more than once across the ladder
The task is sound; the fact is not contiguous. 4.0.0 constructs an empty union, a 4.0.x patch broke it, it threw from 4.0.17 through 4.3.6, and 4.4.0 repaired it — which LF21's own note already said, in the sentence "4.4.0 is a repair, not a new behaviour".
The survey had predicted this before the task existed, and skipping it would have been cheaper. It was built anyway and the gate was allowed to refuse it, because skipping facts on the operator's prediction is how a task set quietly becomes the set of facts that looked easy. The refused artifacts are kept so the refusal can be re-run. S3 reserve #4, LF12 (z.cuid(), 4.4.0) took the slot in the order draw.mjs printed it, with no further choice made; it had not been charged against this subject, so the previously-charged subset stays at 4 of 12.
LF10 never errored
Found while looking for a falling artifact for it. The version 4.4.0 holds — the bisector dated it correctly — but three clauses around that version were wrong, and all three ran in the direction that makes the fact sound less serious than it is.
z.tuple([z.string(), z.string().default("fb")]).safeParse(["a"])
4.0.0 .. 4.3.6 succeeds, returns ["a"] <- length 1, no error, no default
4.4.0 .. 4.5.4 succeeds, returns ["a","fb"]
Published as "materialize in parsed output rather than erroring on an under-filled input", with a stale belief of "an under-filled tuple is a hard length error". No 4.x release errors on one. The pre-4.4.0 failure is a silently short array handed to code that indexes position 1 and reads undefined — which is what S2/silently-wrong is for, and the old wording described a caught error instead. The note's other clause, "an explicit undefined supplied by the caller is preserved", is false on all fifteen: .parse(["a", undefined]) returns ["a","fb"] everywhere. It is now probed separately as LF10b with its own claim.
No charge and no date moves. The correction changed A3's assertion before A3 was written: a check written against the published wording — "an under-filled row must be rejected below 4.4.0" — would have been false at every rung, and the task would have failed admission for a reason that was the fact's fault rather than the task's.
Base rate after four bisected libraries: 14 of 49 dated facts wrong, plus two facts wrong about their own mechanism at the right version (valibot's LF6 severity, JOURNAL/072, and this one).
What is left in D1
- A2 (LF4) — the
tsc --strictgrading path, the last Class A task. The fact is a type error with no runtime shadow, so it needs the compiler, not the runtime. - Six Class N tasks, authored rather than drawn, gated by the inverse flip test.
- Then step 5: BM1 itself.
No Sam gate on any of it. The first gate in this lane is still D2's repo flip.