marmalade: decline published check, choose Go, and open a wal

Adds .loom/cart/current/wal.md as staging for the event log, so conversion moves
entries rather than rewriting them.

published check is declined on the registry argument rather than on not needing it
yet: the command simulates a consumer and a registry with named consumers has real
ones, so an observed fetch beats a synthetic probe and building the probe first
builds a worse version of what is coming. Two falsifiers recorded — registry never
materialising, or registry recording declared consumers rather than observed
fetches, since who says they depend on us is not who can actually read us.
Dropping it also removes the only thing complicating the credential story, because
--as existed almost entirely to serve it.

The insight is kept separately because it outlives the command: a check performed
with your own credential proves nothing, and whoever builds registry's consumer
view needs that before they design it, since the tempting implementation is for
the publisher to verify their own publication.

Go, for a single static binary with no runtime, on a tool that gets installed on
other people's machines and run casually by humans and in loops by agents.
Recorded with its own falsifier: if it only ever runs in one or two places, the
choice was made on a cost nobody pays. And the consequence — list shells out to
git, so git must be on PATH, which makes list the seam if that ever bites.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UTxuSizozEA8yDitPuris
This commit is contained in:
2026-09-07 14:40:20 -04:00
co-authored by Claude Opus 5
parent 76f5aef17a
commit a419222477
2 changed files with 109 additions and 0 deletions
+16
View File
@@ -310,3 +310,19 @@ git -c http.extraHeader="Authorization: token <t>" clone --filter=blob:none …
*Nothing persisted, nothing in the repository.* **Which is the same rule as the *Nothing persisted, nothing in the repository.* **Which is the same rule as the
credential file: the mistake we would most regret is the one that happens by credential file: the mistake we would most regret is the one that happens by
accident.** accident.**
---
## `published check` is declined, and there is a `wal.md` now
**Staged in [`wal.md`](wal.md) rather than here**, *so conversion is a move and not
a rewrite.* **Four entries: the decline and its two falsifiers, the insight that
outlives the command, Go, and `git`-on-`PATH` as the consequence of `list`.**
**Your registry argument is the one that carries it**, *not "we do not need it
yet".* **A probe simulates a consumer; a registry with named consumers has real
ones** — *and an observed fetch beats a synthetic one.*
*Not a rationalisation, on one condition: **that the falsifiers are written down
where somebody will hit them**, which is what makes it a decline rather than a
thing we talked ourselves out of. **They are in the `wal`.***
+93
View File
@@ -0,0 +1,93 @@
# Write-ahead log — cart `marmalade`
**Staging for `.loom/event-log.md`.** *Things decided mid-round that must survive
conversion, written in the shape an entry wants so that converting is a move and
not a rewrite.*
**This file is not a daily and is not annotated.** *If something here is wrong, say
so in your daily and I will change it.*
---
## Declined: `published check`
**Decided:** *not built.* **The `published` noun does not ship; `loomctl` has
`external` and, later, `beads`.**
**Believed to advance:** *`published check` **simulates** a consumer.* **A registry
with named consumers has real ones**, *and an observed fetch beats a synthetic
probe — the probe says a stranger **could** have fetched it, the registry says
somebody **did**.* **Building the probe first is building a worse version of the
thing that is coming.**
**And it removes the only thing complicating the credential story.** *`--as
<context>` existed almost entirely to serve this command;* **without it the config
is one read credential per host**, *which is where we wanted to land anyway.*
**Belief that could be shown wrong, two ways:**
- **`registry` never materialises.** *Then nothing ever asks this question, and the
failure it catches goes on being invisible.*
- **`registry` records *declared* consumers rather than *observed* fetches.** *A
declared consumer does not answer the question at all* — **"who says they depend
on us" is not "who can actually read us"** — *and then this comes back.*
**What it cost to decide:** *the command found three real problems in one
afternoon, one of which turned out to be a false positive it would produce
forever.* **The workaround is one `curl`.** *A real need with a cheap workaround is
a gap, not a missing feature.*
## Keep, even though nothing implements it
**The insight outlives the command and belongs in the log on its own:**
> **A check performed with your own credential proves nothing.** *It helps you
> complete alone an act that, by definition, you cannot* — **and then tells you it
> was fine.**
**Believed to advance:** *whoever builds `registry`'s consumer view needs this
before they design it*, **because the tempting implementation is for the publisher
to verify their own publication**, *which is the same mistake with a database
behind it.*
**Measured, and worth keeping with it:** *`/api/v1/user` gives the acting login and
the repository gives its owner, so **"am I checking as myself" is one request and
not a hard problem.*** *It is a cheap check that nobody thinks to make.*
## Decided: Go
**Decided:** *`loomctl` is written in Go.*
**Believed to advance:** *this is a tool that gets installed on other people's
machines — a laptop, a cluster node, a CI runner — and **a single static binary
with no runtime is the difference between "download it" and "first install a
runtime".*** *The work is HTTP with precise header control, shelling out to `git`,
and reading files; Go's standard library does the first and third with no
dependencies at all.*
**Considered: TypeScript on npm.** *`npm i -g` is a real distribution channel and
the familiar one.* **Not chosen because it puts a runtime between the user and a
tool whose whole job is to be run casually and often**, *including by agents in
loops where start-up cost is paid every time.*
**Belief that could be shown wrong:** *that distribution is the deciding
constraint.* **If `loomctl` ends up only ever running in one or two places, the
binary advantage is worth little** *and the choice was made on a cost nobody pays.*
## Consequence: `git` must be on `PATH`
**`external list` shells out to `git`** — *`clone --filter=blob:none --depth=1
--no-checkout`, then `ls-tree`* — **rather than using a git library.**
**Believed to advance:** *the behaviour we measured across gitea, GitHub and GitLab
is `git`'s behaviour*, **including `--filter` support, the silent fallback when a
server refuses it, and the user's existing credential helpers.** *A library
reimplements all of that and would have to be re-measured.*
**So the tool has a runtime dependency after all**, *just not a language one.*
**`list` is the only command that needs it** — *everything else is HTTP* — **which
makes `list` the seam if `git`-on-`PATH` ever becomes a problem.**
**Belief that could be shown wrong:** *that shelling out stays simple.* **The first
time we need to parse `git`'s output for something it does not print stably**, *the
library trade looks different.*