Two corrections and one new confirmation, all from finishing the sweep I left running last iteration. Refuted, by my own sweep, within the hour: "rotation appears to live only in nested .rat leaf records". That held for GP_TITLE, GP_BUNK and GP_CHALLENGE -- the three archives the sweep had reached when I wrote it -- and fails on GP_DIALOG and GP_DEBRIEFING_PILOTLOG, which rotate top-level elements. Scoping the claim made it cheap to withdraw, but the sentence should have waited for the sweep. Those top-level cases are the best evidence on the disc, and they show up in `screen info --geometry` without a hex dump. GP_DIALOG build 0: pceff03/pceff04 ramp r = 90 -> 30 -> 10 -> 3 -> 0 while alpha ramps 0 -> 255 and they slide into place -- a swing-in settling upright. Build 6: pzeff02 ramps 43 -> 61 -> 75 -> 90 while scaling 112% -> 200% and fading to 0 -- a spin-out. Rows committed as reference data. New: the pivot-anchored scale term in blit, kf.x - pivot*(scale-100)/100, was implemented and reasoned about but never measured, because every element previously examined sits at 100% scale where the term is exactly zero. The ptloop pair scale 600% and 800%, where it is worth 450 and 630 px. Formula predicts centre y = 360.0 for both; capture measures 359.1 and 360.0. Top-left anchoring predicts 810 and 990. Horizontally it makes t-from-position agree with t-from-alpha to 0.33 / 0.65 units against ~8 without it. That agreement does NOT prove linear interpolation -- both fields were inverted through the same linear map, so a shared easing curve cancels. It shows position and alpha ride one shared parameter. Recorded as such. The disc-wide sweep is still running; the count is incomplete, the existence is settled.
361 lines
24 KiB
Markdown
361 lines
24 KiB
Markdown
# Method traps already paid for
|
||
|
||
Each line cost an iteration at least once. They are general — they are not about
|
||
Sylpheed, they are about how this kind of measurement goes wrong.
|
||
|
||
Like [`REFUTED.md`](REFUTED.md), this list had been living in the autonomous
|
||
agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
|
||
✅/🟡/❔ confidence convention itself.
|
||
|
||
## Controls
|
||
|
||
* **Every result needs a control. A control that fails kills the instrument.**
|
||
* **Run the known-positive through a new filter FIRST.** Three filters have been
|
||
killed by their own control. When one fails, **read the known-good's
|
||
disassembly** before assuming a shape.
|
||
* **A measured negative is a result** — but a negative is only as strong as the
|
||
route you ran, so **state its reach**.
|
||
* **A null result needs its cause shown to have happened.**
|
||
* **A result with NO unknowns is suspicious.**
|
||
* **Census the whole set; always run the other population as the control.**
|
||
**Zero partials is stronger than a majority.**
|
||
* **A 2×2 partition is the sharpest general tool** — both off-diagonals empty is
|
||
a law.
|
||
* **Re-derive a doc's own numbers as the control.**
|
||
|
||
## Inference
|
||
|
||
* **Never conclude from ONE sample.**
|
||
* **A law proved on one population is a hypothesis on the next.**
|
||
* **Finding one exception does not imply a family.**
|
||
* **Consistency is not proof. A suggestive coincidence is a coincidence until
|
||
measured.** **An analogy is not a measurement.**
|
||
* **Same layout ≠ same instance.** **Same record-name set ≠ same object.**
|
||
* **A marker is only proven by what it leaves out.**
|
||
* **A high-confidence SCORE is not a high-confidence MECHANISM.**
|
||
* **Knowing HOW MANY is not knowing WHICH.**
|
||
* **Round numbers matching is weak evidence — unless you read the constant.**
|
||
* **My own last-turn result is a hypothesis too.**
|
||
* **A global partition can understate a per-owner one.**
|
||
* **A residual is measured against a population — name it.**
|
||
|
||
## Searching and tooling
|
||
|
||
* **A search that returns thousands has no power; state the reach.**
|
||
* **A substring match is not a hit.** **A regex miss looks like a null result —
|
||
print one raw sample before believing a zero.**
|
||
* **A derived table can be a cross product — measure its shape first.**
|
||
* **After refuting an instrument, sweep everything that depended on it.**
|
||
* **Before measuring how wrong a tool is, read what the tool actually does.**
|
||
* **The instrument must pass its own control.**
|
||
* **Classify a bulk before mining it. The residual is the prize.**
|
||
* **Rank by similarity — the cliff is the finding.** But **read the values
|
||
before trusting the rank.**
|
||
* **Grep the nouns before designing the experiment — and believe it.**
|
||
* **Grep gives you a file list — read *every* file on it.**
|
||
* **The answer is often already in the doc that owns the subject — read it end
|
||
to end.** A 🟡 often names its own route.
|
||
* **Before re-trying a blocked idea, check whether the blocker's own doc already
|
||
tried it.**
|
||
* **Ship a regenerator with every artefact.** An artefact that moves by a pure
|
||
reorder is a tool bug.
|
||
* **Never print per-entry lines from a disc-wide sweep — aggregate.**
|
||
|
||
## Reading the data
|
||
|
||
* **Read what a loader NAMES, not where it stores.**
|
||
* **A field the disc never values still gets named by the loader.**
|
||
* **An indexed read beats a deduped-pool adjacency read.**
|
||
* **Check the whole string set, not the one matching word.**
|
||
* **A dict keyed by record name across a multi-entry pak is a lie.**
|
||
* **A set-difference over names hides reuse — join per USER.**
|
||
* **A self-index names records, not files.**
|
||
* **Case-insensitive hashing means two spellings can be one entry.**
|
||
* **An "unresolved" name may be the wrong kind, namespace or prefix — or part of
|
||
a cut asset.**
|
||
* **A garbled value may be a real string in another encoding.**
|
||
* **Two of my own counts disagreeing is a grammar clue.**
|
||
* **A game's own typo is a join key.**
|
||
* **A bias constant in the code is a join key.**
|
||
* **A prefix trap: enumerate maximal `[A-Za-z0-9_]` runs, not `startswith`.**
|
||
* **Re-deriving a format is not a finding — asking whether its values *resolve*
|
||
is.**
|
||
|
||
## Mechanics that have bitten
|
||
|
||
* **Never hand-convert a decimal VA — print `hex()`.**
|
||
* **`grep -c` counts LINES** — use `grep -o | wc -l`.
|
||
* **`Counter.most_common()` tie-breaks by insertion order — use `sorted()`.**
|
||
* **Raw grep cannot see inside compressed pak entries.**
|
||
* **Commit messages go in a file** (`git commit -F`); a literal `|` in a table
|
||
cell needs escaping; `git log --all -- <path>` can hang.
|
||
|
||
## Runtime / emulator
|
||
|
||
* **Look at the PNG** — and check its dimensions.
|
||
* **"Animating" is not "still in a mission".**
|
||
* **Dedup entity enumerations by position value.**
|
||
* **Do not diagnose timing or liveness under gdb.** `ps %cpu` is cumulative.
|
||
* **Classify screens by whole-image statistics, not named pixels** — a named
|
||
pixel is only valid while the image sits at a known place, and nothing errors
|
||
when it moves.
|
||
* **Do not poll faster than the guest updates** — it manufactures a clean curve
|
||
out of noise.
|
||
* **A probe that never performs the action will "prove" the action does not
|
||
exist.**
|
||
* **The container's Canary binary can be older than the Canary source tree, and
|
||
the failure mode is a hang, not an error.** After a merge into `sylpheed-re`
|
||
the prebuilt `xenia_canary` had no `log_ui_draws`, no `mem_watch`, no
|
||
`create_profile_if_none` — and an unknown cvar makes xenia open an SDL message
|
||
box before logging is up, which headless is an unexplained freeze. Check before
|
||
trusting a harness flag: `nm -C <binary> | grep cvars::<flag>`, and
|
||
`build-canary Release` if it is missing.
|
||
* **A capture armed *at* a screen only ever sees the steady state.** Anything
|
||
about how a screen is built or animated has to be armed *before* it exists.
|
||
Re-arming every few seconds and keeping every log tiles the approach: each F10
|
||
opens a new numbered file and closes the previous one complete.
|
||
* **Measure animation in submitted frames, not in seconds.** `VdSwap` counts are
|
||
the guest's own frames, so an emulator at 80 % of real time does not move them;
|
||
a stopwatch reading does, silently and by an unknown factor.
|
||
* **~~This game's menus drop d-pad presses shorter than ~0.3 s.~~ WITHDRAWN
|
||
2026-08-28 — the menu WRAPS, and I had not measured that.** The claim came from
|
||
reading a cursor that ended up "one item short"; once wrap-around at both ends
|
||
was measured ([`menu-navigation-semantics.md`](menu-navigation-semantics.md)),
|
||
every one of those press counts is exactly right — four presses at 0.12 s moved
|
||
four steps *through the bottom*, which lands one above where a non-wrapping
|
||
menu would put it. **No press was ever dropped.** The real lesson is the
|
||
general one: *a step count is only readable once you know the topology*, and I
|
||
invented a hardware-flakiness story rather than testing the ends of the list.
|
||
Still true and worth keeping: screenshot after every step and read the cursor,
|
||
rather than trusting arithmetic over the press count.
|
||
* **A screenshot taken right after a transition can catch a screen mid-fade.**
|
||
A grab 2.5 s after Ⓑ returned the game to the title showed the title art with
|
||
no `PRESS Ⓐ BUTTON` plate; one second later the plate was there. That very
|
||
nearly went into the corpus as "the returned title has no plate". Sample a
|
||
changing screen several times before writing down what it does *not* contain.
|
||
* **Do not identify a menu cursor by label brightness.** The obvious oracle —
|
||
"the focused label is the brightest row" — fails on this game's menus, because
|
||
the background art is brighter behind some rows than the highlight is. It
|
||
confidently named the wrong item on a frame whose ring was plainly elsewhere.
|
||
Detect the **focus ring** in the gutter left of the labels instead
|
||
(`tools/re-capture/menu_focus.py`, 254 vs <82 — no threshold tuning needed),
|
||
and look at the PNG before believing either.
|
||
* **`screenshot` samples at 0.5 Hz — it cannot time an animation.** Measured:
|
||
~2 s per grab (an `import` of the root plus an ImageMagick crop). A 0.4 s fade
|
||
falls entirely between two samples, which is why a 40-frame burst across a
|
||
screen change looked like an instant cut. For anything timed, record the
|
||
display instead: `ffmpeg -f x11grab -framerate 30 -video_size <W>x<H> -i
|
||
:98+<X>,<Y> -t <secs>`, then read per-frame statistics off the file. Take the
|
||
geometry from `xwininfo -root -tree`, the same way `bin/screenshot` does.
|
||
* **A screen's brightness curve is not its fade quad.** The incoming screen's own
|
||
elements animate in *after* the transition quad has cleared, so mean luminance
|
||
keeps rising long after the fade is over — 1.47 s against a declared 0.97 s on
|
||
one screen. Time the fade from where the frame is *pure black*, and take the
|
||
ramp itself from the keyframes.
|
||
* **A `sound.pak` entry is not a bank.** Entry windows straddle bank boundaries
|
||
(the leading-region effect), so a naive "walk the RIFFs in this entry" gives
|
||
the tail of the previous bank, then one of your own, then the *next* bank's
|
||
header. It looks like a bank with the wrong number of waves. The tell is a
|
||
`BANK id=` that is not the entry's own number, and the fix is the `seek` packet
|
||
counts — they pin each wave's join exactly, so a straddle can be realigned
|
||
rather than thrown away. 4 of 32 BGM banks look like counterexamples until this
|
||
is applied.
|
||
* **Do not time a video whose start you did not see.** An attract cycle sampled
|
||
from partway through measured "≈85 s", which was used to argue it was not the
|
||
137 s `ADV.wmv`. It was `ADV.wmv`; the sampling began 39 s in. Identify a video
|
||
by **content** — match frames against the candidates and check the matched
|
||
playhead advances monotonically — before reasoning about its duration.
|
||
* **A near-black frame has no signature.** In frame-matching, low-contrast frames
|
||
drive every correlation toward zero and the ranking becomes noise; one control
|
||
frame scored 0.000 and another tied the wrong movie at 0.98. Read a dark
|
||
frame's runner-up as *no evidence*, not as evidence for the runner-up.
|
||
* **A screen that never changes is not necessarily hung — it may be a menu.** A
|
||
90-second screenshot loop that presses nothing will report a perfectly healthy
|
||
`DIFFICULTY` menu as a standing hang, and that reading survived in this corpus
|
||
for months. Before calling a static screen a hang, *look at it*, and press
|
||
something.
|
||
* **Never run `ps -ef` in this container.** Each of the three long-lived
|
||
processes carries the whole loop prompt as its argv, so the listing is tens of
|
||
kilobytes of the prompt you already have. Use `pgrep -x <name>` or
|
||
`ps -o pid=,stat= -C <name>`.
|
||
* **A file extension is not a format.** `sound.pak` is full of `.slb` banks and
|
||
names a `.xgs` project, and neither is an XACT container: the whole 1.08 GB
|
||
archive contains zero `XGSF`, `SDBK` or `WBND` magic, and the executable has no
|
||
XACT string at all. The names came from the authoring tool and survived into the
|
||
shipped data. Check for the magic before committing to a parser for the format
|
||
the extension advertises.
|
||
* **A log-polling probe must compare a COUNT, not test for presence.** Timing an
|
||
operation by waiting for its "done" line in a log gives an instant false
|
||
positive if any earlier run left one there. This produced a confident
|
||
"39.5 fps" that was really 0.1 s of matching a stale line — and it disagreed
|
||
with the true 28.5 fps by enough to have flipped a conclusion. Snapshot
|
||
`log.count(marker)` before starting and wait for it to *increase*.
|
||
* **This container kills long emulator runs.** Twice in one session the
|
||
`xenia_canary` process vanished with **no crash line in its own log** — once
|
||
~50 s into a boot, once ~145 s in at 1.15 GB RSS — while the box sat at
|
||
~1 GB free with swap exhausted. Budget dynamic experiments to fit in ~2 minutes
|
||
of guest time, take the measurement early, and never read a disappearance as a
|
||
guest crash without checking the log tail for one.
|
||
* **When a frame-match will not resolve, sample denser before doubting the
|
||
hypothesis.** Identifying a movie from 5-second screenshots gave contrast-23
|
||
frames, a playhead that would not join up, and a runner-up winning one frame —
|
||
it looked like weak evidence for the wrong film. The same question sampled every
|
||
0.5 s (`ffmpeg x11grab` at 10 fps) answered at **0.999 with a strictly monotone
|
||
playhead**. Sparse sampling does not weaken a signal gracefully; it turns it
|
||
into noise that looks like a different answer.
|
||
* **Check what instrumentation the local build already has before declaring a
|
||
question blocked on tooling.** Two Q8 residuals were written off as needing "an
|
||
emulator whose audio path can be observed". The emulator in this container
|
||
already had `xma_param_probe` — visible in the startup CONFIG DUMP the whole
|
||
time — added by this project for exactly that purpose. Read the cvar dump, or
|
||
`nm -C <binary> | grep cvars::`, before concluding you cannot measure something.
|
||
* **"Strings a function references" is not "arguments a function passes".** A
|
||
loose filter over the strings in a caller produced a tidy-looking screen
|
||
vocabulary; recovering the actual register argument at each call site removed
|
||
half of it, including two names that appeared to be corroborated by independent
|
||
measurement. If the claim is about an argument, simulate the registers — the
|
||
cheap proxy manufactures agreement.
|
||
* **A backward scan for `addi rN, …` misses arguments staged through another
|
||
register.** PPC code often builds a pointer in a scratch register and moves it
|
||
into place later (`addi r27, r11, X` … `mr r5, r27`). A backward search for the
|
||
destination register alone found 7 of 48 sites and missed the two known-good
|
||
ones. Simulate forward over a window instead, tracking `lis`/`addi`/`mr`.
|
||
* **Check a measurement against the WHOLE reference set, not the part you were
|
||
reading.** Two observed BGM stream sizes were recorded as matching "no bank's
|
||
declared waves", which spawned a wrong theory that the decoder gets a window
|
||
rather than a whole wave. They match `BGM_103` exactly — the check had covered
|
||
only the `BGM_0xx` rows of the census, because that is the block that had been
|
||
on screen.
|
||
* **`instructions.function` is unpopulated for most rows in `sylpheed.db`.** A
|
||
query keyed on it returns *nothing* rather than erroring — a `bctr` search
|
||
scoped that way reported "no jump tables" for a function with two known ones.
|
||
Scope by `address between <start> and <end_address>` instead, and gate any such
|
||
query on a function whose answer you already know.
|
||
* **Before testing "state X behaves like this", check that your route actually
|
||
reaches state X.** A test of "does Ⓐ work in phase 4 state 0" was run by
|
||
pressing Ⓑ, on the strength of a decoded `4 → state 0` edge — but the same basic
|
||
block also writes the *phase* field, sending it to phase 2. The test probed the
|
||
wrong state and produced a confident refutation of a live hypothesis. When a
|
||
transition sets more than one field, read the whole block, not the one store you
|
||
were looking for.
|
||
* **A default filter can hide a whole screen, and the corpus will record it as
|
||
absent.** `screen list`/`render` filter on `is_build`, which needs a `.rat`
|
||
child; the developer splash has none, so it never appeared — and a page ended up
|
||
stating it "cannot be rendered at all". It renders fine under `--all`. When two
|
||
pages disagree about whether something exists, run the tool both ways before
|
||
believing either.
|
||
* **A logo that appears twice may be two different things.** The boot shows
|
||
`SQUARE ENIX` at ~2 s and again at ~10 s; the first is the splash screen, the
|
||
second is the intro movie's own opening frame. Reading the capture alone gives
|
||
"three logo screens". Cross-check a repeat against what is *supposed* to be
|
||
playing at that moment before counting it as its own screen.
|
||
* **Do not hard-code an expected element count into a structure scan.** Looking
|
||
for a `.rat` record's keyframes, I required 29 strictly-increasing times because
|
||
a header word read `30`. The records hold **three** keyframes in exactly the
|
||
layout I was testing for, and the over-constrained filter reported the layout as
|
||
refuted. Scan for the *shape* (here: `0x??ffffff` fade words at a constant
|
||
stride) and let the count fall out.
|
||
* **Read the target text before writing a patch pattern for it.** Two iterations
|
||
running, a scripted edit to `HANDOFF.md` failed its assertion because the
|
||
paragraph had been rewrapped since the pattern was written — and both times the
|
||
finding landed in `docs/re/` while the page the port agent reads kept the stale
|
||
version. The commit's file count is the tell: if it is one short, an edit was
|
||
silently dropped.
|
||
* **Two renderers agreeing is not evidence the field is right.** The port's
|
||
composite and `sylpheed-cli screen render` matched on `main_menu` to 3/255 —
|
||
and *both* omitted two elements the game draws, because both read one field
|
||
through one decoder. Agreement between consumers of the same decode measures
|
||
the decode's determinism, not its truth. Only a framebuffer capture is an
|
||
independent check. (Reported by the port agent, 2026-08-28, after a capture
|
||
crop found the missing bracket.)
|
||
* **`./target/debug/<bin>` is STALE in this container — `CARGO_TARGET_DIR` is
|
||
redirected.** The Dockerfile sets `CARGO_TARGET_DIR=/sylph-home/re/target-container`
|
||
so a fresh `cargo build` writes there, while `./target/debug/sylpheed-cli`
|
||
remains whatever was built on the host, hours old. A decoder fix was verified
|
||
against the stale binary and produced byte-identical "before" and "after"
|
||
renders — which reads exactly like "the change had no effect" rather than "you
|
||
ran the old code". Run the binary cargo actually wrote, or `cargo run`.
|
||
* **A pivot-equality test conflates rounding with real breakage.** Checking
|
||
`pivot == texture/2` over `GP_TITLE` flagged 74 % as mismatched, which reads as
|
||
a systemic decode failure. Split by magnitude it is 17 exact, 54 off by ≤ 1 px
|
||
(odd dimensions rounding), and only **24 off by > 8 px** — and those 24 are the
|
||
real finding, concentrated on one element family. Bucket a mismatch by size
|
||
before reporting a rate.
|
||
* **I have now broken the "read the target text first" rule three times.** Each
|
||
time a scripted `HANDOFF.md` edit asserted on a paragraph that had been rewrapped
|
||
by an earlier edit in the same session, and each time the finding landed in
|
||
`docs/re/` while the port's page kept the stale text. Writing the rule down was
|
||
not enough; the working fix is mechanical — `grep`/`sed -n` the target paragraph
|
||
in the same command that patches it, and check the commit's file count.
|
||
* **"The nearest header after the name" is not a name→header mapping.** Looking
|
||
for each sprite's `T8aD` header by searching for its name and taking the next
|
||
`T8aD` returned *the same header for every sprite* — all the names live together
|
||
in the declaration table near the top of the bundle, so "next" is always the
|
||
first one in the file. It failed its own control instantly: different sprites
|
||
reported identical dimensions. Match on something the header itself carries
|
||
(here width × height against the decoded PNGs) rather than on proximity.
|
||
* **`cargo build` passing does not mean `cargo test` compiles.** Adding a field to
|
||
`T8adImage` built the library fine in 1.48 s — and broke two *test-only* struct
|
||
literals, so `cargo test` failed to compile with exit 101. A green build on the
|
||
binary is not a gate for a struct change; run the tests before believing a
|
||
data-structure edit is safe.
|
||
* **Detach long background work with `setsid`, or a tool-call timeout kills it.**
|
||
Three attempts to run the disc-gated test suite in the background died at exit
|
||
143 with an empty log — the timeout's SIGTERM reached the whole process group.
|
||
`setsid nohup cargo test … &` survives, and the run then completes across later
|
||
tool calls. An empty log from a "background" job usually means it was killed,
|
||
not that it produced nothing.
|
||
* **Validate a recommendation before leaving it as advice.** Having concluded a
|
||
question was undecodable from the disc, I named a per-draw GPU capture as the
|
||
next route "because it reads the blend state". It does not — checking the
|
||
capture's own source showed it records textures and vertex attributes and no
|
||
blend registers. A named next step is a claim like any other.
|
||
* **Name the element from the draw's own coordinates before building on it.** A
|
||
skewed draw in a title capture was called "the swoosh" because the swoosh is the
|
||
screen's only diagonal element — an identification by elimination, never checked
|
||
against the draw's NDC extent. It was wrong: the quads span the full screen and
|
||
beyond, the swoosh is a 234-pixel band. Five iterations of analysis pointed at
|
||
the wrong element on the strength of it. Converting the coordinates takes one
|
||
line and should come first.
|
||
* **A census over a bundle's top-level table is not a census over the bundle.**
|
||
The keyframe rotation field read "always zero on this screen" for several
|
||
iterations because every scan walked `GP_TITLE` build 4's **declaration
|
||
table**, and the rotated elements are **nested leaf records** reached through
|
||
an `opt ` link. The bytes were right; the *reach* was wrong, and a negative
|
||
stated without its reach reads like a fact about the disc. Say which region a
|
||
negative covers, and check whether the thing you are looking for lives outside
|
||
it.
|
||
* **Do not assume 4-byte alignment when scanning raw bundle bytes.** A nested
|
||
`RATC` blob starts wherever the parent's chunk stream leaves it — `ptloop01.rat`
|
||
sits at `0xbb5966` — so its 40-byte keyframe blocks are odd-aligned. A scanner
|
||
that filtered candidates on `%4 == 0` found **0/3** of its own control blocks
|
||
and under-counted the corpus by **16 341** blocks, all of them nested. It cost
|
||
nothing to catch, because the control was in the script.
|
||
* **`pkill -f <pattern>` matches the shell running it.** `pkill -f kfscan.py`
|
||
from a `bash -c` whose command line contains `kfscan.py` kills its own shell:
|
||
the tool call returns exit 143/144 and the edit that was queued behind it never
|
||
runs. The same trap makes `pgrep -f` self-report — a "still running? yes" that
|
||
was the shell seeing itself, on a job that had already finished. Use
|
||
`pgrep -x`, or match on a path the current command line does not contain.
|
||
(This is the second `ps`/`pgrep` entry in this file; the first is about
|
||
`ps -ef` dumping the loop prompt.)
|
||
* **Grep a legend and you count the legend.** A sweep for elements with a
|
||
rotation reported "1 element" in every build on the disc — the header line
|
||
`a=alpha r=rot°` matched the ` r=` pattern. A uniform count across
|
||
heterogeneous inputs is the tell. Make the pattern require the *value*
|
||
(` r=-?[0-9]+`), and sanity-check that a known-negative build reports zero.
|
||
* **A pattern over the archives you happened to check is not a negative.** I
|
||
wrote "rotation appears to live only in nested leaf records", correctly scoped
|
||
to the three paks I had swept — and the sweep refuted it on the fourth, within
|
||
the hour, because the alphabet had not reached `GP_DIALOG` yet. Scoping the
|
||
claim was what made it cheap to withdraw, but the better move is to let the
|
||
sweep finish before writing the sentence at all: a negative that is still
|
||
running is not a finding, it is a prediction.
|
||
* **A field that is implemented is not a field that is measured.** The
|
||
pivot-anchored scale term had been in `blit` for months and reasoned about in
|
||
the handoff, and no capture had ever exercised it, because every element anyone
|
||
had looked at was at 100 % scale where the term is identically zero. Look for
|
||
the case that makes a term *large* — here 600 % and 800 % scale, worth 450 px —
|
||
and check it there. A term you cannot distinguish from zero has not been
|
||
verified by any amount of agreement.
|