Skip to content

Prove what a known-absent image costs on a second ask - #271

Merged
iderex merged 2 commits into
mainfrom
what-a-known-absent-image-costs-a-second-time-51
Aug 31, 2026
Merged

Prove what a known-absent image costs on a second ask#271
iderex merged 2 commits into
mainfrom
what-a-known-absent-image-costs-a-second-time-51

Conversation

@iderex

@iderex iderex commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

The issue this belongs to

Closes #51

What changed

The third done-when of #51 was narrowed on 2026-08-30, and this is that condition
proven and the file that contradicted it corrected.

src/artwork/presence.rs carried a paragraph in its own header saying that the
condition was about keeping the absence. It was, before the narrowing. It is not
now: the condition reads that a second ask for a known-absent image within one
screenful makes no network call because the answer carries no address for one to
be made from
, with nothing about the absence outliving the ask that produced it.
A reader of that
file was being sent to a condition that had moved, so the paragraph now says what
moved and what did not - the two landed records are untouched, an absence is
still not a cached kind, and nothing in that module writes to a store.

Two tests beside the type, sharing one helper whose only parameter is the tag.
The absent answer is asked for twice and produces no request either time, so
nothing reaches the shared-fetch bookkeeping and there is no key for a fetch to
be started from. The same two asks for an image that does exist start one fetch
and join it on the second, which is 0053 coalescing on the entry key.

What failure it prevents

The first test alone would pass in a tree that fetches nothing whatever it is
given, which is the shape of a guard that looks at nothing. The second is what
makes the first about the absence rather than about the tree. Without the pair,
the condition would be recorded as met on an assertion that could not have
failed.

The header paragraph is the other half. A file that describes a condition which
has since moved is read as current, and the next person to work on the absence
would have gone looking for a cache entry that this record deliberately does not
create.

Evidence

git rev-parse HEAD
aa2efdbe3bebeda4034ea75925259345fed6550e
git rev-parse origin/main
2ba16aead4f46ce9e50a0e4e3735160212de1a0a

The two commands CONTRIBUTING.md names:

cargo build --locked --all-targets ; echo "exit=$?"
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.07s
exit=0

cargo test --locked 2>&1 | grep -E '^test result:' \
  | awk '{p+=$4; f+=$6} END {printf "%d line(s), %d passed, %d failed\n", NR, p, f}'
9 line(s), 652 passed, 0 failed

which is two more than the 650 on the mainline this branches from, and the two
are the ones below:

cargo test --locked --lib artwork::presence
test artwork::presence::tests::a_second_ask_for_a_known_absent_image_starts_no_fetch ... ok
test artwork::presence::tests::the_same_two_asks_for_an_image_that_exists_share_one_fetch ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 481 filtered out

The two legs that read this file's shape:

bash .github/lint/lint.sh check
Every lint the groups above carry was refused, outside the register printed with it.

bash .github/format/format.sh check
Every tracked source file above is written the way the formatter would write it.

What a guard here refuses, and the proof it bites

Both directions were watched failing, one violation at a time, and the tree was
restored after each.

The absent test. WhatTheItemHas::of_kind changed so that a metadata entry
with no tag answers with a request anyway, by replacing the early return with
let tag = tag.unwrap_or("abc123");:

cargo test --locked --lib artwork::presence::tests::a_second_ask_for_a_known_absent_image_starts_no_fetch
test ... FAILED
thread '...' panicked at src\artwork\presence.rs:306:9
test result: FAILED. 0 passed; 1 failed

cargo test --locked --lib artwork::presence::tests::the_same_two_asks_for_an_image_that_exists_share_one_fetch
test ... ok
test result: ok. 1 passed; 0 failed

The neighbour. SharedFetches::hold changed so that a second hold on one
entry always pushes rather than joining, by deleting its join arm:

cargo test --locked --lib artwork::presence::tests::the_same_two_asks_for_an_image_that_exists_share_one_fetch
test ... FAILED
test result: FAILED. 0 passed; 1 failed

cargo test --locked --lib artwork::presence::tests::a_second_ask_for_a_known_absent_image_starts_no_fetch
test ... ok
test result: ok. 1 passed; 0 failed

So each of the two goes red for its own reason and neither goes red for the
other's.

What a guard already here refused, and what it cost

The first commit on this branch wrote the narrowed condition into the module
header in the words the ruling used, including "across sessions or scrolls".
no-view-vocabulary refused it on the runner:

##[error]no-view-vocabulary: src/artwork/presence.rs:62://! across sessions or scrolls. That is a property of
##[error]1 line(s) broke an invariant above.

It was right to. 0003 places a scroll offset outside this core by name, and the
rule holds what has been named, so a comment inside src/ teaching the core that
word is the crossing it exists against. The second commit says the same thing
without it. This is recorded rather than squashed away because it is a guard on
this board catching a real crossing on a real branch, which is the evidence that
rule was added for.

I did not run that leg locally before the first push. The run that found it is
the runner's, which is the same argument #81's shell half was built on: the
analysed set and the executed set come apart quietly, and the run is what notices.

What this does not cover

Nothing here is about a wire. Nothing in this tree opens a connection, so "no
network call" is asserted as "no request, and therefore no key to start a fetch
from" rather than as a socket that was not opened. That bound is written into the
test module's own header rather than left in this body.

No absence is kept, and this change adds no way to keep one. 0006's list of
cached kinds and 0043's closing of it are untouched. What the second ask is
derived from is the item's metadata, which 0006 does list.

No fetch is coalesced against a server. The second test drives
SharedFetches directly, which is the bookkeeping a fetch would be started and
stopped from. #53's own conditions announce tiles against a running core and none
of them is touched here.

No behaviour changed. Only the header paragraph, the test-module header and
two tests. of_kind, request and is_absent are byte-identical to the
mainline.

Several legs were not run on this machine before the first push. codeql.yml,
zizmor.yml, scorecard.yml, dependencies, targets and invariants were
not, and shellcheck is not installed here. The section above is what one of
those six then found. This branch adds and edits no shell and no workflow.

Who has read it

Nobody but me. There was no second reader available for this change, and the
evidence above stands in place of one rather than the question being left open.

The third done-when of #51 was narrowed on 2026-08-30: a second ask for a
known-absent image within one screenful makes no network call, because the answer
carries no address for one to be made from, and nothing about the absence is kept
across sessions or scrolls. The module said the opposite in its own header - that
the condition was about keeping the absence, which is what it read before the
narrowing - so a reader of this file was sent to a condition that had moved.

Two tests, one helper, and the only difference between them is the tag. A known
absent image answers twice with no request, so nothing reaches the shared-fetch
bookkeeping and there is no key to start a fetch from. The same two asks for an
image that does exist start one fetch and join it on the second, which is 0053
coalescing on the entry key.

The second exists because the first would pass in a tree that fetches nothing
whatever it is given. Both directions were watched failing. Answering with a
request where the metadata carried no tag reddens the first and leaves the second
green; dropping the join arm from SharedFetches::hold reddens the second and
leaves the first green.

What this does not prove is anything about a wire. Nothing in this tree opens a
connection, so "no network call" is asserted as "no request, and therefore no key
to start a fetch from" rather than as a socket that was not opened.

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex iderex self-assigned this Aug 31, 2026
…t learn (#51)

The paragraph added in the commit before this one wrote that nothing about the
absence is kept "across sessions or scrolls", which is the narrowed condition in
the words the ruling used. `no-view-vocabulary` refused it, and it was right to:
0003 places a scroll offset outside this core by name, and the rule holds what has
been named rather than a boundary, so a document comment inside `src/` teaching
the core that word is the crossing it exists against.

The sentence says the same thing without it: nothing about the absence outlives
the ask that produced it. The guard was watched refusing the first form on the
runner rather than reasoned about, and this is the repair.

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex
iderex merged commit 0860e37 into main Aug 31, 2026
26 checks passed
@iderex
iderex deleted the what-a-known-absent-image-costs-a-second-time-51 branch August 31, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Treat a missing image as a first-class answer and never as an error

1 participant