diff --git a/.loom/externals/.locks b/.loom/externals/.locks index ebeca21..cf4920f 100644 --- a/.loom/externals/.locks +++ b/.loom/externals/.locks @@ -11,3 +11,4 @@ git.hypertheory-labs.dev/loom/bedrock/sibling-facets.md https://git.hypertheory- git.hypertheory-labs.dev/loom/bedrock/starting.md https://git.hypertheory-labs.dev/loom/bedrock/raw/branch/main/.loom/published/starting.md "b9eefba0f4668a496ccfc6a1377277f0721456d2" public git.hypertheory-labs.dev/loom/cart/cart.md https://git.hypertheory-labs.dev/loom/cart/raw/branch/main/.loom/published/cart.md "15331f1a9cc81bf61a44830cfbb7c274f4c2b119" public git.hypertheory-labs.dev/loom/externals/externals.md https://git.hypertheory-labs.dev/loom/externals/raw/branch/main/.loom/published/externals.md "50673ccffc14d57150ac0a9027b0712d9dcf940d" +git.hypertheory-labs.dev/loom/loom-cli/guarantees.md https://git.hypertheory-labs.dev/loom/loom-cli/raw/branch/main/.loom/published/guarantees.md "432822b3f91ec7c7acd2c868490b7cdcde5db99a" public diff --git a/.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.md b/.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.md new file mode 100644 index 0000000..432822b --- /dev/null +++ b/.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.md @@ -0,0 +1,93 @@ +# 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 url etag [ 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.* + +--- + +*Verified fetchable by somebody who is not us on 2026-09-08.* diff --git a/.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.usages.md b/.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.usages.md new file mode 100644 index 0000000..a316de7 --- /dev/null +++ b/.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.usages.md @@ -0,0 +1,27 @@ +# Usages — `loomctl` guarantees + +**This site is built with the tool.** *Every reference page in it was adopted with +`external add`, and the reconcile that produced this one went through `check` and +`apply`.* **So "what of ours depends on it" has a short, real answer for once.** + +| what the page guarantees | what of ours leans on it | +|---|---| +| `check` reports and does not fix | **`npm run check` in CI.** *A build that repaired what it found would commit on a runner, with no cart and nobody to decide* | +| the `ETag` is the publisher's, verbatim | `scripts/generate.mjs` — *the guide stamps in frontmatter are those etags; a computed hash would fire the stale banner on every whitespace change* | +| it never writes over the network | *the deploy holds no write credential — `git-sync` clones anonymously and `loomctl` is never on the cluster at all* | +| `add` refuses what is adopted, and stages a differing copy | *how all eight original documents were locked after being fetched by hand, without one byte being rewritten* | + +## What we depend on that the page explicitly does not promise + +**The command surface.** *`scripts/publish-site.sh` and the README quote +`loomctl external add loom/ .md` verbatim.* **The page says names, +flags and output are `--help`'s business and nothing should parse them** — *we do +not parse them, but a person following our README will type them.* + +> **So a renamed command breaks our documentation and not our build**, *and no +> check will catch it*, **because the thing that moved is not a document we +> adopted.** + +*Recorded rather than solved. It is the same class as the sub-page staleness limit +in `HANDOFF.md`: the lock watches documents, and some of what we lean on is not a +document.* diff --git a/astro.config.mjs b/astro.config.mjs index fefba29..283174a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,10 +1,11 @@ import { defineConfig } from 'astro/config' import starlight from '@astrojs/starlight' +import sidebar from './src/sidebar.json' with { type: 'json' } -// The sidebar is autogenerated from directories, so adopting a document and -// re-running `npm run generate` is the whole of adding a page. Nothing here -// names a document; a config that listed them would be a second place to -// update and would go stale silently. +// Nothing in this file names a document or a section. The sidebar is generated +// from .loom/externals/.locks, so adopting anything and re-running +// `npm run generate` is the whole of adding it — a config that listed them +// would be a second place to update and would go stale silently. export default defineConfig({ site: 'https://loom.hypertheory-labs.dev', srcDir: './src', @@ -21,13 +22,9 @@ export default defineConfig({ }, ], editLink: { baseUrl: 'https://git.hypertheory-labs.dev/loom/docs/_edit/main/' }, - sidebar: [ - { label: 'Start here', link: '/' }, - { label: 'bedrock', autogenerate: { directory: 'bedrock' } }, - { label: 'externals', autogenerate: { directory: 'externals' } }, - { label: 'annotating', autogenerate: { directory: 'annotating' } }, - { label: 'cart', autogenerate: { directory: 'cart' } }, - ], + // Generated by scripts/generate.mjs from the locks. Adopting from a new + // repository adds a section here with no edit to this file. + sidebar, customCss: ['./src/styles/loom.css'], }), ], diff --git a/scripts/generate.mjs b/scripts/generate.mjs index c8c8519..411c1df 100644 --- a/scripts/generate.mjs +++ b/scripts/generate.mjs @@ -232,6 +232,15 @@ for (const [repo, records] of [...sections].sort(([a], [b]) => a.localeCompare(b else if (!existing) console.log(` created ${repo}/index.mdx (blank guide, yours to fill)`) } +// The sidebar named its sections by hand, which made adopting from a new +// repository a config edit — a second place to update, which is the thing the +// autogenerated directories were already avoiding one level down. +const sidebar = [ + { label: 'Start here', link: '/' }, + ...[...sections.keys()].sort().map((repo) => ({ label: repo, autogenerate: { directory: repo } })), +] +writeFileSync(join(root, 'src/sidebar.json'), JSON.stringify(sidebar, null, 2) + '\n') + console.log( `generate: ${written.length} pages from ${sections.size} sections` + (ACK ? ', stamps refreshed' : staleTotal ? `, ${staleTotal} stale` : ''), diff --git a/src/content/docs/loom-cli/guarantees.md b/src/content/docs/loom-cli/guarantees.md new file mode 100644 index 0000000..80e59b5 --- /dev/null +++ b/src/content/docs/loom-cli/guarantees.md @@ -0,0 +1,111 @@ +--- +title: What `loomctl` guarantees +editUrl: false +loom: + generated: true + path: git.hypertheory-labs.dev/loom/loom-cli/guarantees.md + source: https://git.hypertheory-labs.dev/loom/loom-cli/raw/branch/main/.loom/published/guarantees.md + etag: '"432822b3f91ec7c7acd2c868490b7cdcde5db99a"' + visibility: public +--- +**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 url etag [ 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.* + +--- + +*Verified fetchable by somebody who is not us on 2026-09-08.* + + +
+ +This page is a copy of a document published by `loom/loom-cli`, rendered here. +The source is [https://git.hypertheory-labs.dev/loom/loom-cli/raw/branch/main/.loom/published/guarantees.md](https://git.hypertheory-labs.dev/loom/loom-cli/raw/branch/main/.loom/published/guarantees.md) and is what the copy is checked against. + +What of ours depends on it: `.loom/externals/git.hypertheory-labs.dev/loom/loom-cli/guarantees.usages.md` + +
diff --git a/src/content/docs/loom-cli/index.mdx b/src/content/docs/loom-cli/index.mdx new file mode 100644 index 0000000..f20f236 --- /dev/null +++ b/src/content/docs/loom-cli/index.mdx @@ -0,0 +1,19 @@ +--- +title: loom-cli +loom: + writtenAgainst: + - path: git.hypertheory-labs.dev/loom/loom-cli/guarantees.md + etag: '"432822b3f91ec7c7acd2c868490b7cdcde5db99a"' +--- +This page is yours. Nothing overwrites it. + +Put what a copy cannot carry here — a worked example, the order to read things +in, the thing that only makes sense once you have done it twice. + +Prefer an example to an explanation. An explanation is a second saying of a rule +that is owned on one of the pages beside this one, and it goes stale silently. An +example goes stale visibly, because the artifacts in it are the wrong shape. + +The pages in this section are copies of what `loom/loom-cli` publishes, and are +regenerated. When one of them moves, this page gets a banner asking whether it is +still true — the build cannot answer that, so it asks. diff --git a/src/sidebar.json b/src/sidebar.json new file mode 100644 index 0000000..cde49c3 --- /dev/null +++ b/src/sidebar.json @@ -0,0 +1,36 @@ +[ + { + "label": "Start here", + "link": "/" + }, + { + "label": "annotating", + "autogenerate": { + "directory": "annotating" + } + }, + { + "label": "bedrock", + "autogenerate": { + "directory": "bedrock" + } + }, + { + "label": "cart", + "autogenerate": { + "directory": "cart" + } + }, + { + "label": "externals", + "autogenerate": { + "directory": "externals" + } + }, + { + "label": "loom-cli", + "autogenerate": { + "directory": "loom-cli" + } + } +]