Skip to content

Put the explanation in the README, and keep it from rotting - #211

Closed
abernier wants to merge 1 commit into
description-ratchetfrom
readme-explainer
Closed

Put the explanation in the README, and keep it from rotting#211
abernier wants to merge 1 commit into
description-ratchetfrom
readme-explainer

Conversation

@abernier

Copy link
Copy Markdown
Member

The one-line description is what the index can afford. It is not what a
reader wants once they have opened the example, and until now there was
nothing else: <name>.md went straight from the facts block to 200 lines
of TSX.

The explainer lives in the example's own README.md, under the badges.
That file already exists in all 170 -- three badges, a degit line and a
thumbnail -- so this is additive: no new file, no new convention. GitHub
renders it, degit carries it into whatever the reader scaffolds, and
bin/build-llms.mjs inlines it into <name>.md under the facts, which is
what finally puts an explanation into the document agents are served.
llms.txt is untouched and keeps its single line: one line to choose, the
full explainer once chosen.

Structure is fixed, length is not -- the problem, the technique, the
pitfalls. A fixed structure resists drift better than a word ceiling, and a
demo that needs 200 words should not be padded to 400.

Prose that explains code goes stale on its own, so it gets a mechanism, and
the obvious one is wrong. A hash of the source stored next to the explainer
would have fired on 161 examples the day the prettier hook landed, and the
only rational response would have been to re-stamp 161 hashes without
reading a word -- training precisely the reflex that makes a tripwire
worthless. What fires on the right commits instead: every identifier the
prose puts in backticks must still appear somewhere in the example's
src/. A concatenation and a search, no import parsing, no package
resolution. useMask disappears in a drei migration and it breaks on
precisely the explainers that named it; a formatting sweep never wakes it.
And it reaches further than renames -- in a declarative r3f scene the
technique is the set of components used.

Deliberately looser than the rule on apis, which is checked against the
example's imports: prose may name the demo's own components (Aquarium,
Turtle) and its props (stencil in gl={{ stencil: true }}). What it
gives up is small -- an identifier deleted from the code but surviving in a
comment still passes.

//#lint:metadata gains examples/*/{README.md,CONTEXT.md} as inputs, and
its source glob widens to the shaders and stylesheets the prose is now
checked against. Cached past either, the rule stops being one, which is the
same argument that put examples/*/src/** there for apis.

docs/agents/domain.md goes multi-context in the same change. The
per-example CONTEXT.md this relies on had no convention behind it -- that
rewrite had been sitting in a stash since #193, with no issue and no
branch, and adding this issue's two rules to the single-context version
would have meant writing them twice. Those rules: teach is a legitimate
producer of CONTEXT.md alongside /domain-modeling, and no demo gets one
that merely restates its README.

aquarium is the first example written this way, and the case the skill
already used to name the problem. Its explainer is the one thing a reader
cannot get from the source by looking: nothing writes the mask's reference
into the stencil buffer, so the contents fail the test everywhere on the
canvas and are drawn only into MeshTransmissionMaterial's own render
targets, which carry no stencil buffer. The glass is not showing what is
behind it -- it is the only surface its contents appear on, which is why
spheres sitting outside the box read as suspended in it. Its description
and apis come from the same reading, so the ratchet list in
bin/description-exceptions.mjs loses its first entry.

Absence is the normal state. --explain is multi-session, interactive work
driven by curiosity about a particular demo, not a programme across 170. An
example with an explainer is better; one without is fine.

Closes #199


Stack created with GitHub Stacks CLIGive Feedback 💬

The one-line `description` is what the index can afford. It is not what a
reader wants once they have opened the example, and until now there was
nothing else: `<name>.md` went straight from the facts block to 200 lines
of TSX.

The explainer lives in the example's own `README.md`, under the badges.
That file already exists in all 170 -- three badges, a `degit` line and a
thumbnail -- so this is additive: no new file, no new convention. GitHub
renders it, `degit` carries it into whatever the reader scaffolds, and
`bin/build-llms.mjs` inlines it into `<name>.md` under the facts, which is
what finally puts an explanation into the document agents are served.
`llms.txt` is untouched and keeps its single line: one line to choose, the
full explainer once chosen.

Structure is fixed, length is not -- the problem, the technique, the
pitfalls. A fixed structure resists drift better than a word ceiling, and a
demo that needs 200 words should not be padded to 400.

Prose that explains code goes stale on its own, so it gets a mechanism, and
the obvious one is wrong. A hash of the source stored next to the explainer
would have fired on 161 examples the day the prettier hook landed, and the
only rational response would have been to re-stamp 161 hashes without
reading a word -- training precisely the reflex that makes a tripwire
worthless. What fires on the right commits instead: every identifier the
prose puts in backticks must still appear somewhere in the example's
`src/`. A concatenation and a search, no import parsing, no package
resolution. `useMask` disappears in a drei migration and it breaks on
precisely the explainers that named it; a formatting sweep never wakes it.
And it reaches further than renames -- in a declarative r3f scene the
technique *is* the set of components used.

Deliberately looser than the rule on `apis`, which is checked against the
example's *imports*: prose may name the demo's own components (`Aquarium`,
`Turtle`) and its props (`stencil` in `gl={{ stencil: true }}`). What it
gives up is small -- an identifier deleted from the code but surviving in a
comment still passes.

`//#lint:metadata` gains `examples/*/{README.md,CONTEXT.md}` as inputs, and
its source glob widens to the shaders and stylesheets the prose is now
checked against. Cached past either, the rule stops being one, which is the
same argument that put `examples/*/src/**` there for `apis`.

`docs/agents/domain.md` goes multi-context in the same change. The
per-example `CONTEXT.md` this relies on had no convention behind it -- that
rewrite had been sitting in a stash since #193, with no issue and no
branch, and adding this issue's two rules to the single-context version
would have meant writing them twice. Those rules: `teach` is a legitimate
producer of `CONTEXT.md` alongside `/domain-modeling`, and no demo gets one
that merely restates its README.

`aquarium` is the first example written this way, and the case the skill
already used to name the problem. Its explainer is the one thing a reader
cannot get from the source by looking: nothing writes the mask's reference
into the stencil buffer, so the contents fail the test everywhere on the
canvas and are drawn only into `MeshTransmissionMaterial`'s own render
targets, which carry no stencil buffer. The glass is not showing what is
behind it -- it is the only surface its contents appear on, which is why
spheres sitting outside the box read as suspended in it. Its `description`
and `apis` come from the same reading, so the ratchet list in
`bin/description-exceptions.mjs` loses its first entry.

Absence is the normal state. `--explain` is multi-session, interactive work
driven by curiosity about a particular demo, not a programme across 170. An
example with an explainer is better; one without is fine.

Closes #199
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Put the explanation in the README, and keep it from rotting

1 participant