D664 - An origin list, with every failure named
Status: measured Date: 2026-09-10
One origin per source was two wrong answers
A corpus source named exactly one place to get its assets: a release, or a sibling checkout. Both are right some of the time and neither is right always. A checkout is the fast path for whoever has one and absent for everyone else; a release is slower and always there. With one field, a manifest either broke for people without the sibling or ignored it for people with it.
A source now carries sources - origins tried in order,
first one that answers wins.
Bare strings, classified here
The manifest lists origins as plain strings so a person can paste a release URL beside a relative path without also learning a keyword for each. Reading them is this code's job:
Origin::classify("https://…") // Url
Origin::classify("../obscene/build") // Path
Origin::classify(r"D:\builds\probe") // PathThat last one is why this is a tested function rather than an inline
guess. A Windows path contains a colon and C: is not a
scheme, so the test is :// and not :.
Every failure is kept, and that is the point
Attempt carries what answered and what
did not, with each reason. A fallback that reports only its success
hides the fact that the fast path is broken - the sibling checkout could
have been missing for a month while the release quietly served every
fetch, and the manifest would look healthy. All of them failing is an
error naming every attempt, so the next person knows whether to fix a
path or a URL.
Pure, so the ordering is testable without a network
first_that_answers takes the fetching as a closure. The
ordering, the reporting and the give-up condition are decided in a
function that touches neither filesystem nor network, and the effectful
part is supplied by the caller - the shape principle 8 asks for, and the
reason three tests cover it exhaustively in microseconds.
Written test-first. The failures were
cannot find function first_that_answers,
cannot find type Attempt,
unresolved import Origin - which is what a failing test
should say before there is anything to pass.
What is wired and what is not
The manifest carries the field, corpus list shows every
source and its target, and the decision layer is complete and tested.
The fetch path still uses
repo/tag/path: walking
an origin list at fetch time is the next step, and wiring it half-way
would have left a manifest that describes something the code does not
do.