osprey converts: the design is the log, and the cart is gone
The round is over and its artifact is .loom/event-log.md — fifteen entries, each carrying the belief that could show it wrong, all tagged osprey so it stays findable what else was in the room. No spec is written. A spec flattens everything to equal confidence, which is how the specimen managed to be wrong with a straight face within a day of being proposed. The specimen is discarded rather than promoted; the story of its being wrong is in the log, where it can be found, and the artifact would only mislead somebody who read it without the round beside it. Reconciles externals.md, which check flagged as the one drifted document of eight. The new copy carries the 404 row, so the gap filed against it is closed and externals.gaps.md is deleted — at reconciliation rather than at repair, because a facet describes the local pair and the gap stayed true of the copy we held until we fetched. The entry recording that our 404 behaviour is no longer provisional is the one that would have been easiest to skip and is the reason the log exists. No shelf: nothing was unresolved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018UTxuSizozEA8yDitPuris
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
# Event log
|
||||
|
||||
**Appended, newest last, never revised.** *A later entry supersedes an earlier one
|
||||
by saying so.*
|
||||
|
||||
*Entries tagged `osprey` were all considered in a single sphere of understanding.*
|
||||
|
||||
---
|
||||
|
||||
## 2026-09-07 — what this tool is `osprey`
|
||||
|
||||
**Decided:** *`loom-cli` is a fetcher and a comparator.* **It fetches a document
|
||||
you depend on and tells you whether the publisher's copy has moved.** *It reports
|
||||
and never repairs.*
|
||||
|
||||
**Believed to advance:** *every act in the loom model is a file in somebody's
|
||||
repository — publishing is writing one, adopting is fetching a URL, homing a gap
|
||||
is an `mv`.* **Almost nothing needs a program**, so the program should be the
|
||||
part that cannot be done by hand: an HTTP request, repeated.
|
||||
|
||||
**Belief that could be shown wrong:** *that reporting is enough.* **If every
|
||||
report is followed by the same manual act, we have moved the work rather than
|
||||
removed it**, and the missing command will be obvious.
|
||||
|
||||
## 2026-09-07 — the design lives here and not in a spec `osprey`
|
||||
|
||||
**Decided:** *this log is the artifact of `osprey`.* **No specification document
|
||||
is written, and the specimen that opened the round is discarded.**
|
||||
|
||||
**Believed to advance:** *every entry here carries a belief that could be shown
|
||||
wrong, so a reader can see which parts are load-bearing and which were guesses.*
|
||||
**A spec flattens all of it to equal confidence** — *which is how the specimen
|
||||
managed to be wrong, with a straight face, within a day of being written.*
|
||||
|
||||
**Belief that could be shown wrong:** *that a reader can build from a log.* **It
|
||||
is ordered by time and not by topic**, so somebody arriving reads chronologically
|
||||
and holds the corrections in their head. *Fine at fifteen entries and not at
|
||||
eighty. When a newcomer cannot build from it without a guide, the guide is the
|
||||
next thing to write — and not before.*
|
||||
|
||||
## 2026-09-07 — freshness is a conditional request `osprey`
|
||||
|
||||
**Decided:** *the tool records the publisher's `ETag`, verbatim and opaque, and
|
||||
sends it back as `If-None-Match`.* **It never computes a hash of anything.**
|
||||
|
||||
**Believed to advance:** *`externals` requires it, and we now have the empirical
|
||||
reason as well as the stated one.* **On gitea a raw file's `ETag` is its git blob
|
||||
hash; on GitHub it is not.** *A design that compares a local hash to a remote
|
||||
`ETag` works on exactly one host by coincidence.*
|
||||
|
||||
**Belief that could be shown wrong:** *that `ETag` is stable enough to lock on.*
|
||||
**A proxy, a CDN, or a host that regenerates the header per request would produce
|
||||
a change report where nothing changed.** *Untested against anything but gitea and
|
||||
GitHub.*
|
||||
|
||||
## 2026-09-07 — supersedes nothing: the path is for a person `osprey`
|
||||
|
||||
**Decided:** *the origin URL is recorded in the lock, not derived from the stored
|
||||
path.*
|
||||
|
||||
**Believed to advance:** *the path `\.loom/externals/<host>/<path>.md` does not
|
||||
round-trip.* **Measured:** *the document we hold as
|
||||
`git.hypertheory-labs.dev/loom/externals/externals.md` is served from
|
||||
`/loom/externals/raw/branch/main/.loom/published/externals.md`* — **the stored
|
||||
path has dropped the route, the branch, and `.loom/published/`.**
|
||||
|
||||
*The third is not routing.* **`publication.md` makes `.loom/published/` the whole
|
||||
contract**, and a tree that erases it cannot say whether a copy came from
|
||||
somebody's published surface or from a file they may rename at will.
|
||||
|
||||
**Belief that could be shown wrong:** *that people will still read the path as a
|
||||
location.* **If anybody writes code that parses it back into a URL, the path
|
||||
should stop looking like one.**
|
||||
|
||||
## 2026-09-07 — the lock, and what it holds `osprey`
|
||||
|
||||
**Decided:** *one record per adopted document in `.loom/externals/.locks`: the
|
||||
**resolved** origin URL, and the `ETag` it came with.*
|
||||
|
||||
**Believed to advance:** *the specimen said there would be no lock file, on the
|
||||
strength of the `ETag`-as-blob-hash claim.* **That claim failed twice**, so the
|
||||
file exists and is named for what it is. *It was briefly called `.etags`, from
|
||||
when we believed there would be one field.*
|
||||
|
||||
**Resolved, and not the short form.** *Measured: gitea `303`s
|
||||
`/loom/externals/raw/externals.md` to `/raw/branch/main/…`* — **so a lock holding a
|
||||
short URL is locked to whatever the default branch is at the time you ask**, and a
|
||||
branch rename reports as a change in the document.
|
||||
|
||||
**Belief that could be shown wrong:** *that one file is cheap.* **Two fetches in
|
||||
one round conflict inside it, and the conflict is in a file no human can resolve
|
||||
by reading.** *If that bites, it becomes one record per document and the tree is
|
||||
mirrored twice.*
|
||||
|
||||
## 2026-09-07 — unlocked is a state `osprey`
|
||||
|
||||
**Decided:** *a document with no lock is reported as unlocked.* **`check` never
|
||||
adopts whatever the remote is currently serving as the lock.**
|
||||
|
||||
**Believed to advance:** *adopting it would assert the local copy is the one being
|
||||
served, which is the thing you were about to check.* **It is the hash assumption
|
||||
in a different coat, and it fails silently in the one case that matters — a copy
|
||||
somebody edited.**
|
||||
|
||||
**Belief that could be shown wrong:** *that anybody will run `pull` again to fix
|
||||
it.* **If unlocked documents simply accumulate, the report is noise and something
|
||||
has to lock them.**
|
||||
|
||||
## 2026-09-07 — `404` is unresolved, and that is no longer provisional `osprey`
|
||||
|
||||
**Decided:** *`check` reports a `404` as unresolvable — the document was withdrawn
|
||||
or we have lost access — and names both readings without picking one.*
|
||||
|
||||
**Believed to advance:** *over HTTP they are the same response, because a host
|
||||
that distinguished them would leak the existence of things you may not see.*
|
||||
|
||||
**This entry exists because the status of the behaviour changed and the code did
|
||||
not.** *It began as a local workaround recorded in a `.gaps.md` against
|
||||
`externals`, which listed `410` and not `404`.* **`externals` has since added the
|
||||
`404` row, so the gap is closed and the facet is deleted at this reconciliation.**
|
||||
|
||||
> **The workaround is not retired. It is now the specified behaviour.** *Unchanged
|
||||
> in the code and entirely changed in status — and this log is the only place that
|
||||
> says so.* **Somebody inheriting this will find the behaviour and go looking for
|
||||
> the gap that justified it, and find nothing.**
|
||||
|
||||
**Belief that could be shown wrong:** *that reporting both readings is useful.*
|
||||
**If in practice it is always one of them, the report is a ritual** — *and that is
|
||||
worth knowing.*
|
||||
|
||||
## 2026-09-07 — declined: `check` does not resolve the `404` over ssh `osprey`
|
||||
|
||||
**Considered:** *the two readings **are** distinguishable over ssh — permission
|
||||
denied against repository not found — and `externals` now says so.* **Demonstrated
|
||||
here by accident:** *`loom/settled` returned `404` over HTTP while an ssh clone of
|
||||
it succeeded.*
|
||||
|
||||
**Not done, because:** *it needs a key, a non-default port, and a second
|
||||
transport* — **and it would be fixing rather than reporting**, which is the rule
|
||||
this design held all round.
|
||||
|
||||
**Belief that could be shown wrong:** *that a person will do it.* **The ssh
|
||||
disambiguation is one command and it is in the document; if nobody ever runs it,
|
||||
the ambiguity was never actionable and reporting it was theatre.**
|
||||
|
||||
## 2026-09-07 — declined: `init` `osprey`
|
||||
|
||||
**Considered and rejected**, not deferred.
|
||||
|
||||
**Because:** *its temptation is to scaffold, and four empty directories assert four
|
||||
things nobody has decided.* **A file that carries no delta should not exist.**
|
||||
|
||||
**Belief that could be shown wrong:** *that starting is easy without it.* **If
|
||||
people repeatedly fail to start**, *the useful version creates one file and asks
|
||||
one question* — **and creating the tree is still not the feature.**
|
||||
|
||||
## 2026-09-07 — declined: worktree, clone; and where a round lives `osprey`
|
||||
|
||||
**Decided:** *the cart lives on the default branch; the work is isolated on a
|
||||
branch named for the cart.*
|
||||
|
||||
**Believed to advance:** *a cart is a venue and the work is an artifact.* **`cart`
|
||||
says three states are visible in a listing, and a branch makes all three
|
||||
invisible** — *a venue only visible if you know which branch to check out is not a
|
||||
venue.* **Both dailies land on the default branch, one commit per exchange.**
|
||||
|
||||
**Declined: a worktree, and a separate clone.** *Both isolate concurrent working
|
||||
directories, and `cart` says there is one live cart, ever.* **They solve a problem
|
||||
the agreement says cannot exist.**
|
||||
|
||||
**Belief that could be shown wrong:** *that the dailies and the work have
|
||||
different audiences.* **If a daily needs to quote a file that only exists on the
|
||||
branch, the split makes the daily unreadable from where it lives**, and the answer
|
||||
collapses to one branch for both.
|
||||
|
||||
## 2026-09-07 — `publish` is renamed `reachable`, and it earned its place `osprey`
|
||||
|
||||
**Decided:** *the command is `loom reachable <path>` — one anonymous request
|
||||
against a document in `.loom/published/`.*
|
||||
|
||||
**Believed to advance:** *the old name said the tool performs publication, which
|
||||
is the one thing the model says it never does.* **It performs a fetch with a
|
||||
different subject**, which keeps it inside a fetcher and a comparator.
|
||||
|
||||
**It was nearly cut for being a third kind of thing. Then it was validated three
|
||||
times in one afternoon**, against loom's own repositories:
|
||||
|
||||
```
|
||||
loom/settled 404 anon the page written to fix "settled is private"
|
||||
jeffry/homelab-cluster 404 anon and bedrock's public starting page named it
|
||||
as the better answer
|
||||
loom/.loom 200 anon fetchable — but not where a reader lands
|
||||
```
|
||||
|
||||
**All three are now fixed.** *The third was not a `reachable` failure and is
|
||||
recorded as the tool's boundary:* **`reachable` answers *can anybody fetch this*
|
||||
and does not answer *will anybody find it*.** *The second is not testable by a
|
||||
fetcher and a comparator, and trying is the first step in the tool becoming
|
||||
something else.*
|
||||
|
||||
**Belief that could be shown wrong:** *that publication failures are common enough
|
||||
to need a command.* **Three for three is a small sample from one publisher in one
|
||||
week.**
|
||||
|
||||
## 2026-09-07 — the `ETag`/blob coincidence is a migration aid `osprey`
|
||||
|
||||
**Recorded so it is not rediscovered as a good idea.**
|
||||
|
||||
*With eight adopted documents and no locks, `check` was run by hand by hashing the
|
||||
local copies and comparing to remote `ETag`s* — **the exact thing the convention
|
||||
forbids** — **and it worked**, because on gitea the two coincide. *It found
|
||||
exactly one drifted document, correctly.*
|
||||
|
||||
**It is worth doing once, on gitea, to lock what was fetched by hand before the
|
||||
tool existed. It is not a mechanism.**
|
||||
|
||||
> **The coincidence has now been found twice and rejected twice.** *The next person
|
||||
> to notice it will think they have found the good idea again.*
|
||||
|
||||
## 2026-09-07 — annotate to ask; write in your own file to assert `osprey`
|
||||
|
||||
**Decided:** *responses between two presences are correspondence — each writes in
|
||||
their own file — and annotation is reserved for asking or challenging.*
|
||||
|
||||
**Believed to advance:** *the freeze is not "you cannot edit", it is "you cannot
|
||||
edit without resolving what was said".* **An annotation creates an obligation**,
|
||||
which makes it the blocking form and correspondence the non-blocking one.
|
||||
|
||||
*And the cost is practical: **dissolving a multi-pass file is expensive**, so the
|
||||
cost of annotating rises with the length of the thing annotated.* **Annotate
|
||||
early, or accept the cost when the question is worth blocking on.**
|
||||
|
||||
**Belief that could be shown wrong:** *this rule is in neither `cart` nor
|
||||
`annotating`.* **It is our reading of their text, and `cart` is loom's** — *they
|
||||
may say we have it wrong.*
|
||||
|
||||
## 2026-09-07 — why this tool exists, in one story `osprey`
|
||||
|
||||
**Gitea's ssh is on port `2222`.** *I did not know that. I tried to clone, got
|
||||
`Permission denied (publickey)`, and spent three tool calls and a guess chasing it
|
||||
as an authentication problem before finding the port.*
|
||||
|
||||
**The fact was published.** *`jeffry/homelab-cluster`, in `.loom/published/gitea.md`,
|
||||
says:*
|
||||
|
||||
> **A clone URL without the port will not work**, and the failure looks like an
|
||||
> authentication problem rather than a wrong port.
|
||||
|
||||
**It named my failure before I had it, and I could not read it** — *the repository
|
||||
was not fetchable by anybody who is not its owner.*
|
||||
|
||||
**This happened inside the round that was designing the fix**, *and it failed for
|
||||
the reason that round had just spent two passes identifying.* **A document that is
|
||||
correct, published, and unreachable is worth exactly as much as one that was never
|
||||
written.**
|
||||
|
||||
**Believed to advance:** *nothing in this log is a stronger reason for the tool to
|
||||
exist.* **`reachable` is why the document can be fetched. `pull` and `check` are
|
||||
why it is still true when you read it.**
|
||||
|
||||
**Belief that could be shown wrong:** *that the tool would have helped.* **I would
|
||||
have had to already depend on that document to have pulled it** — *and the thing I
|
||||
needed was the one I did not know I was missing.* **A fetcher does not solve
|
||||
discovery, and this story is partly a discovery problem wearing a freshness
|
||||
problem's clothes.**
|
||||
Reference in New Issue
Block a user