the externals convention, adopting annotating using itself
How a repository records what it depends on, and finds out when it changes. Pull what you use; two facets beside it; ETag freshness; reconciliation running the other way; venues for what you cannot fetch; gaps, with moving a file as the homing act. Built on bedrock's sibling facets, whose three open choices are answered in .loom/externals/git.hypertheory-labs.dev/loom/annotating/annotating.usages.md — the convention adopting annotating using itself. That is the cheapest available test of whether it works. It also states in public the answer whose absence kept two agreements frozen from 2026-08-21: the pair is released by replacement, never by rewriting. A source you did not write is not yours to rewrite, and the protocol never said what to do instead. Nobody chose badly; nobody was asked. The first copy of annotating here was written by hand. You cannot fetch and annotate before the thing that says how exists — self-hosting is a test, not a derivation. Note: loom/annotating does not exist yet, so the external's origin path currently resolves to nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+47
@@ -0,0 +1,47 @@
|
||||
# Usages — `annotating`
|
||||
|
||||
**We cast the three choices [sibling facets](https://git.hypertheory-labs.dev/loom/bedrock)
|
||||
leaves to a convention.** *Answered here as prompts, in `annotating`'s own
|
||||
form.*
|
||||
|
||||
## Select: What is the facet called?
|
||||
- [ ] `notes`
|
||||
- [x] **`usages` and `gaps`** — *two facets, because reconciliation asks a
|
||||
different question of each: **did their change affect what we do**, and
|
||||
**did their change fill this**.*
|
||||
|
||||
## Select: What fixes the source while a facet exists?
|
||||
- [ ] the existence of the facet file
|
||||
- [x] **a lock on the publisher's `ETag`**
|
||||
|
||||
**Note:** *the source is not ours, so its stability is not ours to assert. **The
|
||||
`ETag` is theirs and it is the only honest lock.** It also makes the freeze and
|
||||
the change-check one mechanism instead of two.*
|
||||
|
||||
## Question: How is the pair released?
|
||||
|
||||
**By replacement, never by rewriting.** *A new copy arrives as a candidate, the
|
||||
facets are reconciled against it, and the pair is replaced whole.*
|
||||
|
||||
***This is the answer `annotating` does not give, and its absence is not
|
||||
theoretical:*** *an adopted agreement froze on 2026-08-21 and stayed frozen for
|
||||
three weeks, because the protocol says to dissolve by rewriting the source and
|
||||
the source belonged to somebody else.* **Nobody chose badly. Nobody was asked.**
|
||||
|
||||
---
|
||||
|
||||
## — claude-substrate
|
||||
> **A facet is owned by whoever wrote the facet, never by whoever wrote `x.md`.**
|
||||
|
||||
**This is the sentence the whole convention rests on**, and it is why an external
|
||||
works at all: *we can say what we think about a document we cannot touch.*
|
||||
|
||||
## — claude-substrate
|
||||
|
||||
**We are an intermediary, not a consumer**, and this file is doing something the
|
||||
convention has not modelled. **`cart` adopting `annotating` says *we use
|
||||
`.notes.md`* — a usage.** *We are saying **consumers of this convention use
|
||||
`.usages.md`** — a prescription.*
|
||||
|
||||
**Flagged rather than solved.** *It is the first thing to look at if this file
|
||||
starts feeling like the wrong shape.*
|
||||
@@ -0,0 +1,72 @@
|
||||
# Externals
|
||||
|
||||
**How a repository records what it depends on, and finds out when it changes.**
|
||||
|
||||
## Pull what you use
|
||||
|
||||
**You fetch a copy of somebody's document and keep it** at
|
||||
`.loom/externals/<host>/<path>.md`. *The path says where it came from, so nothing
|
||||
has to record an origin.*
|
||||
|
||||
**Pull what you need to understand, not everything it depends on.** *A document
|
||||
you fetch may refer to others; follow one when you hit something you do not know.
|
||||
**Pre-resolving that is how you get a `node_modules`.***
|
||||
|
||||
## Two facets beside it
|
||||
|
||||
- **`.usages.md`** — *what we use, and **which of our artifacts depend on it***
|
||||
- **`.gaps.md`** — *what we expected here and did not find*
|
||||
|
||||
> **A usage that does not name what it justifies is half a usage.** *"We use the
|
||||
> tailnet approach" is weak. **"We use the tailnet approach — see
|
||||
> `manifests/ingress.yaml`" is the whole value**, because it answers the only
|
||||
> question reconciliation asks.*
|
||||
|
||||
## Freshness is a conditional request
|
||||
|
||||
**Locked on the publisher's `ETag`, verbatim — never a hash you compute.** *A
|
||||
fetch that normalises whitespace breaks a local digest and reports a change that
|
||||
did not happen.*
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **`304`** | nothing changed |
|
||||
| **`200`** | changed — the new copy is a candidate, not a replacement |
|
||||
| **`410`** | gone — follow whatever the response points at |
|
||||
|
||||
## Reconciliation runs the other way
|
||||
|
||||
**You cannot fold your facets back into their document.** *So the question is
|
||||
not what do we rewrite here:*
|
||||
|
||||
> **Given what changed in theirs, what do we change in ours?**
|
||||
|
||||
**The facets usually survive unchanged.** *What moves is the manifests, the
|
||||
config, the code that a usage named — which is why a usage names them.*
|
||||
|
||||
**And gaps reconcile too**, which is the half nobody builds for: *a new version
|
||||
may have filled one, and nothing will tell you.*
|
||||
|
||||
**The new copy replaces the old pair wholesale.** *There is no merging a document
|
||||
you do not own.*
|
||||
|
||||
## Venues, for things you cannot fetch
|
||||
|
||||
**`.loom/venues/<name>.md`** — *Kafka, React, HTTP.* **Choices we made about
|
||||
something with no document to hang them on.**
|
||||
|
||||
*If there is a document, hang it there instead: **put a choice where
|
||||
reconciliation will look for it.***
|
||||
|
||||
## Gaps that belong to nobody
|
||||
|
||||
**`.loom/gaps/`** — *a need with no owner.* **The test: could you say whose job
|
||||
this is?** *If yes, it is a claim against them and belongs in their `.gaps.md`.*
|
||||
|
||||
> **Moving a file from `gaps/` into an external's `.gaps.md` is how a gap gets
|
||||
> homed.** *The position is the claim.*
|
||||
|
||||
**A gap records the local workaround beside the need.** *"We are using Docker Hub
|
||||
for now."* **Forgetting it was provisional is the disease; the provisional answer
|
||||
is fine** — and when the gap is finally homed, every workaround that should be
|
||||
retired is findable.
|
||||
Reference in New Issue
Block a user