Put the explanation in the README, and keep it from rotting - #211
Closed
abernier wants to merge 1 commit into
Closed
Put the explanation in the README, and keep it from rotting#211abernier wants to merge 1 commit into
abernier wants to merge 1 commit into
Conversation
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
30 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The one-line
descriptionis what the index can afford. It is not what areader wants once they have opened the example, and until now there was
nothing else:
<name>.mdwent straight from the facts block to 200 linesof TSX.
The explainer lives in the example's own
README.md, under the badges.That file already exists in all 170 -- three badges, a
degitline and athumbnail -- so this is additive: no new file, no new convention. GitHub
renders it,
degitcarries it into whatever the reader scaffolds, andbin/build-llms.mjsinlines it into<name>.mdunder the facts, which iswhat finally puts an explanation into the document agents are served.
llms.txtis untouched and keeps its single line: one line to choose, thefull 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 packageresolution.
useMaskdisappears in a drei migration and it breaks onprecisely 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 theexample's imports: prose may name the demo's own components (
Aquarium,Turtle) and its props (stencilingl={{ stencil: true }}). What itgives up is small -- an identifier deleted from the code but surviving in a
comment still passes.
//#lint:metadatagainsexamples/*/{README.md,CONTEXT.md}as inputs, andits 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 forapis.docs/agents/domain.mdgoes multi-context in the same change. Theper-example
CONTEXT.mdthis relies on had no convention behind it -- thatrewrite 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:
teachis a legitimateproducer of
CONTEXT.mdalongside/domain-modeling, and no demo gets onethat merely restates its README.
aquariumis the first example written this way, and the case the skillalready 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 rendertargets, 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
descriptionand
apiscome from the same reading, so the ratchet list inbin/description-exceptions.mjsloses its first entry.Absence is the normal state.
--explainis multi-session, interactive workdriven 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 CLI • Give Feedback 💬