loom's .usages.md for this page found the hole. The docs site depends on the command surface — its README and publish script tell a person to type loomctl external add loom/<repo> <doc>.md — and this page explicitly does not promise it. Nothing parses the command, which is exactly why no check would catch a rename: the thing that moved is not a document anybody adopted. The answer is not to promise the surface, which would freeze the CLI. It is to promise that a change to it lands on this page — which consumers already lock — so a rename reports 200 the day it happens. The exclusion goes from "you are on your own" to "you will be told", and it costs one append-only section. Same shape as a supersession in the event log: the record is not that the thing never changes, it is that the change is findable by whoever depended on it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018UTxuSizozEA8yDitPuris
115 lines
4.8 KiB
Markdown
115 lines
4.8 KiB
Markdown
# What `loomctl` guarantees
|
|
|
|
**Not what it does — `--help` says that, and the commands will change.** *This is
|
|
what will keep being true while they do.*
|
|
|
|
---
|
|
|
|
## It grants no access, and records where the copy came from
|
|
|
|
**`loomctl` reads what your credentials already let you read.** *Everything it
|
|
does is possible with copy and paste.* **It is a mast, not a lock** — *the point
|
|
is to make the wrong thing deliberate, not impossible.*
|
|
|
|
> **What it adds over a paste is provenance.** *A pasted document cannot answer
|
|
> "where did this come from, and were we allowed to have it" — not because the
|
|
> question is hard, but because the evidence is gone.*
|
|
|
|
## It never writes over the network
|
|
|
|
**No push, no publish, no `POST`, no token that needs write scope.** *Every byte
|
|
it writes is a file in your working tree.* **Committing and pushing are yours**,
|
|
*because the consequences of a push land on people a tool cannot experience.*
|
|
|
|
**A credential given to `loomctl` should never carry write scope**, *and if one
|
|
does, nothing here will use it.*
|
|
|
|
## Freshness is a conditional request against the publisher's `ETag`
|
|
|
|
**Stored verbatim, opaque, never a hash we compute.** *A fetch that normalises
|
|
anything breaks a local digest and reports a change that did not happen.*
|
|
|
|
*This is `externals`' rule and `loomctl` is a second holder of it. **It is stated
|
|
here so that the tool holding it is a fact somebody can find**, and so that
|
|
breaking it is visible rather than silent* — **a specimen was written in this
|
|
repository that computed a hash instead, and it was wrong within a day.**
|
|
|
|
**The URL in a lock is resolved.** *A short form follows whatever the default
|
|
branch is at the time you ask, so a branch rename would report as a change in the
|
|
document.*
|
|
|
|
## It reports; it does not repair
|
|
|
|
**Nothing is overwritten.** *A document that moved upstream is written to a
|
|
staging area as a candidate, and taking it is a separate act.* **A local copy
|
|
that differs from what the publisher serves is left alone** — *it is the only
|
|
evidence that something changed while nothing was watching.*
|
|
|
|
**`add` adopts what is absent and refuses what is already adopted.** *A document
|
|
that is present but unlocked is locked only when the bytes are identical to what
|
|
the publisher serves*, **so a lock's claim — this copy is the one being served —
|
|
is verified rather than assumed.**
|
|
|
|
## The lock file
|
|
|
|
**`.loom/externals/.locks`, one record per adopted document, tab-separated,
|
|
ordered by path.**
|
|
|
|
```
|
|
path <TAB> url <TAB> etag [ <TAB> visibility ]
|
|
```
|
|
|
|
- **`path`** — *relative to `.loom/externals/`, and **for a person to read**.* **It
|
|
does not round-trip to a URL**; *it drops the route, the branch, and the
|
|
publisher's `.loom/published/`.*
|
|
- **`url`** — *the resolved origin, branch and all.*
|
|
- **`etag`** — *the publisher's, verbatim, including its quotes.*
|
|
- **`visibility`** — *optional. What the source could be read as **when it was
|
|
fetched**: `public` or `not-public`.* **Never `private`** — *an anonymous
|
|
request tells those two apart and nothing finer.*
|
|
|
|
**Records with three fields remain valid.** *A repository does not stop working
|
|
because the tool learned something new.*
|
|
|
|
## What is not promised
|
|
|
|
**The command surface.** *Names, flags and output are `--help`'s business and may
|
|
change. Nothing should parse them.*
|
|
|
|
**The generated orientation file's format.** *It is byte-deterministic within a
|
|
version so that its diff is readable; it is not stable across versions.*
|
|
|
|
**That visibility is precise.** *The signal distinguishes public from not-public
|
|
and nothing finer, so it cannot see two repositories private to different people
|
|
— which is the case where adopting between private repositories genuinely widens
|
|
access.* **The tool says so where it reports it, rather than implying a verdict it
|
|
has not earned.**
|
|
|
|
**That anything is checked when you are not looking.** *Nothing here runs on a
|
|
schedule, and a document nobody checks is a document nobody is checking.*
|
|
|
|
## What is promised about the things that are not promised
|
|
|
|
**The command surface may change. This page will say when it does.**
|
|
|
|
*A consumer whose README tells a person to type `loomctl external add loom/<repo>
|
|
<doc>.md` depends on that command by name — **not by parsing it, which is why no
|
|
check would ever catch a rename**. The thing that moved would not be a document
|
|
they adopted.*
|
|
|
|
> **So the exclusion is narrower than "you are on your own".** *We do not promise
|
|
> the surface holds; **we promise that a change to it lands here**, on a page you
|
|
> can lock* — **and a lock on this page reports `200` the day a command is
|
|
> renamed.**
|
|
|
|
**That is the whole mechanism, and it costs one section:**
|
|
|
|
### Surface changes
|
|
|
|
*Append-only, newest last. Nothing yet — the commands have not been renamed since
|
|
this page existed.*
|
|
|
|
---
|
|
|
|
*Verified fetchable by somebody who is not us on 2026-09-08.*
|