loom-cli's builder tried to run check against a real tree and could not. The stored path does not round-trip to a URL: we hold git.hypertheory-labs.dev/loom/externals/externals.md and the document is served from /loom/externals/raw/branch/main/.loom/published/externals.md, measured as a 404. Two segments are dropped and the second is not routing. The raw route and branch are recoverable only by knowing the host's URL shape and guessing a branch name. And .loom/published/ — which publication.md says is the entire contract — means a consumer's tree did not record whether a copy came from a published surface or a file its owner may rename at will. The short form is worse than incomplete: a host may redirect it to whatever the default branch is at the time you ask, so a lock holding one is locked to a moving target and a branch rename reports as a change in the document. Locks record the resolved URL. This is the ETag mistake one layer down, and the builder named the appetite behind both: the design is beautiful when nothing is written down, and both times what made it possible was a property of one host. Second occurrence, so it is recorded as a pattern to check for. Also records that gitea's ETag being the blob hash is a migration aid rather than a mechanism — the builder used it to check eight documents with no locks at all, which is worth doing once and nothing after. The next person to notice the coincidence will think they found the good idea again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.1 KiB
Event log
Decisions about this convention. Appended, newest last, never revised. An entry states what was decided, what it is believed to advance, and the belief that could turn out false.
Decided (2026-09-07, loom + claude-substrate — discovered, cart: osprey):
404 is named in the convention as two answers wearing one status, and a
client reports both readings rather than picking one.
Advances a consumer not being told the wrong one of the document was withdrawn and you no longer have access.
Because it was filed as a gap against this document by loom-cli, using this
document's own test — could you say whose job it is? It was ours. The
table listed 304, 200 and 410 and not 404, while a host returns 404
for both readings by design: one that distinguished them would leak the
existence of things you may not see.
Over ssh they are distinguishable — permission denied against repository not found — so a client with both transports should say which it used.
Decided (2026-09-07, loom + claude-substrate — discovered, cart: osprey):
a facet describes the local pair. A gap is true of the copy you hold, not of
the document upstream, so a publisher fixing their end does not close it.
Advances a consumer's tree never describing a document that is not in it.
Because we nearly deleted a consumer's .gaps.md on the grounds that the
upstream document had been repaired. Their copy still lacked the row. The
second presence in osprey caught it, and the general form follows from the thing
this whole convention rests on — the copy is theirs and everything beside it is
ours — which we had not followed through to reconciliation.
So a gap closes at reconciliation, not at repair.
And the consequence we would not have reached: what survives is not the gap, it is what the gap justified. A workaround is often not retired by a fix — it stops being a workaround and becomes the specified behaviour, unchanged in the code and entirely changed in status. That change is invisible where the code is, so it is an entry in the consumer's own log — otherwise somebody inheriting the workaround goes looking for the gap that justified it and finds nothing.
A closed gap is not a decline: a decline is what you considered and did not do; a closed gap is what you needed and got. Opposite sign, and filing one as the other puts a thing you wanted into a list of things you rejected.
Decided (2026-09-07, loom + claude-substrate — discovered, cart: osprey):
the path does not record the origin. A lock does, holding the resolved URL and
the publisher's ETag, in .loom/externals/.locks.
Advances the one command that has to send a request being able to construct one.
Because loom-cli's builder tried to run check against a real tree and
could not. The stored path does not round-trip to a URL — we hold
git.hypertheory-labs.dev/loom/externals/externals.md and the document is served
from /loom/externals/raw/branch/main/.loom/published/externals.md. It 404s,
measured.
Two segments are dropped and the second is not routing:
- the host's raw route and the branch — recoverable only by knowing that host's URL shape and guessing a branch name
.loom/published/— whichpublication.mdsays is the entire contract. So a consumer's tree did not record whether a copy came from a published surface or from a file its owner may rename at will.
And the short form is worse than incomplete: a host may redirect it to whatever the default branch is at the time you ask, so a lock holding one is locked to a moving target and a branch rename reports as a change in the document.
This is the
ETagmistake one layer down, and the builder named the appetite behind both: the design is beautiful when nothing is written down, and both times what made it possible was a property of one host.
Second occurrence, so it is a pattern rather than an incident: when a design claims something is derivable and therefore need not be recorded, check whether the derivation is a fact about the general case or about the host in front of you.
Finding (2026-09-07, claude-substrate — cart: osprey): gitea's ETag
being the blob hash is a migration aid, not a mechanism.
loom-cli's builder ran check across eight documents with no locks at all,
by hashing local copies and comparing — the exact thing this convention
forbids — and it worked, because on this host the two coincide.
It is worth doing once, to lock what was fetched by hand before a tool existed. It is worth nothing after that, and it works on gitea only.
Recorded because the next person to notice the coincidence will think they have found the good idea again, and there is now a log entry saying it was found twice and rejected twice.
Seven of the eight were byte-identical to upstream, so this host's raw serving normalises nothing — which is a fact about this host and not a licence.