Skip to content

docs: a contributing guide, held to the same gates as the rest of the prose - #82

Merged
donislawdev merged 2 commits into
mainfrom
docs/contributing-guide
Sep 7, 2026
Merged

docs: a contributing guide, held to the same gates as the rest of the prose#82
donislawdev merged 2 commits into
mainfrom
docs/contributing-guide

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

Stacked on #81.

The repository had a code of conduct, a security policy, issue forms and
CODEOWNERS, and nothing saying what a change has to satisfy before it can go in.
GitHub surfaces this file in two more places than those four - the new issue
form and the new pull request form - so it is the first thing a contributor
reads.

What is in it

Written to save an evening rather than to be complete. It carries the things
that are unusual here and would waste somebody's time if they found out
afterwards: the size is exact or it is an error, the bytes of a generated file
are a contract, nothing is written over, silence is banned, there is no outgoing
connection ever, a new dependency needs a licence check, and every change in
behaviour comes with a test that fails without it.

Translations get their own section, because that is the contribution this
project can take from somebody who does not write Go. Where the catalogue lives,
that description is generated and not to be translated, that a placeholder has
to stay spelled the way it is, and that a language may carry more plural forms
than English does.

It also states the thing that would waste the evening: the window does not
offer a language switch yet
, so a contributed catalogue ships and English is
still what it answers in. Saying so is the point of the section.

Four existing guards now read it, rather than it getting one of its own

guard what it stops
englishFiles ASCII only, flat hyphens, no semicolons
TestTheInstallInstructionsCarryTheBuildTags a guide telling somebody to build without the tag hands them a binary whose AVIF encoder reads past the end of a buffer
TestTheBuildFloorIsThePinnedToolchainAndTheDocumentsSaySo a fourth copy of the minimum Go version rotting away from go.mod
TestNothingThatDirectsAPersonPointsAtAnotherProject a link left pointing at the sibling repository these files get copied from

The third is renamed from ...AndTheReadmeSaysSo, because it is no longer only
the readme. Two of them took a shared list of the documents that teach somebody
how to build, and one took a filename parameter, so none of them names README
twice.

Four mutations, all caught: the tag dropped from the build command, a Go
version go.mod does not admit, an issue link pointing at the sibling project,
and a semicolon.

No changelog entry

That file is for changes somebody running tfg would notice, and this is not
one.

Full suite green, preflight --quick green.

🤖 Generated with Claude Code

donislawdev and others added 2 commits September 7, 2026 18:48
The command line has warned about this since the ceiling was measured on
2026-08-26. The window said nothing at all: TooLargeToReadBack had two callers
and not one of them was in internal/gui.

So somebody who generated 25 000 files from the window ended up with a
directory that tfg verify and tfg cleanup both refuse, and no warning anywhere.
The manifest is the only authority over what may be removed, so those files
could never be cleaned up by this tool again.

It is the kind of parity gap D1 loses most easily. Not something the engine can
do from one surface and not the other, which is what the parity guard looks
for, but something one surface SAYS and the other does not - and both surfaces
reach the same engine, so nothing there could see it.

The observation recorded this as a question about the manifest schema, on the
grounds that notes are per file and this one is per run. That premise was
false, and finding out was most of the work. The command line does not read
this off the manifest either: it works it out from the plan and prints it
before the first byte. manifest.TooLargeToReadBack was put where it is exactly
so the two surfaces could not come to different conclusions about one run. What
was missing was a caller. The schema does not move and manifest_version stays
1.0.

One method arrives, (*Manifest).ReadBackReach, because the count of entries
carrying a note is already kept while entries are added. Working it out a
second time would mean walking every file again and getting it subtly wrong
when a failed entry gains a note of its own.

The window says it in two places, because it cannot say anything in the middle
of a run - a widget touched from a worker is a race, and two of those were
found on CI:

  - after Preview, which is the window's answer to --dry-run. engine.Run with
    DryRun builds the whole document, so the answer is there for the asking.
  - when a run finishes, immediately after the line saying what the run did and
    ahead of any other note. This is the one that matters: Preview is a button
    somebody may never press, and that person is the one left with the
    directory.

Four guards, four mutations.

The pair for Preview was written wrong first and the probe said so. It set a
200 B size while the window was on its default format, which is the first in
the registry - avif - so both previews were REFUSED. The negative half passed
while proving nothing, because a screen saying "check the settings marked
above" says nothing about a manifest ceiling either. Both now choose txt and
both assert the preview was accepted before reading anything into what it said.

The guard for a finished run costs 26 s, because it really writes 22 345 files.
runFinished has no cheaper seam, and this is the only guard covering the case
the observation is actually about.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… prose

The repository had a code of conduct, a security policy, issue forms and
CODEOWNERS, and nothing telling somebody what a change has to satisfy before it
can go in. GitHub shows this file in two more places than those four - the new
issue form and the new pull request form - so it is the first thing a
contributor reads.

It is written to save an evening rather than to be complete. The things in it
are the ones that are unusual here and would waste somebody's time if they
found out afterwards: the size is exact or it is an error, the bytes of a
generated file are a contract, nothing is written over, silence is banned, there
is no outgoing connection ever, a new dependency needs a licence check, and
every change in behaviour comes with a test that fails without it.

Translations get their own section, because that is the contribution this
project can take from somebody who does not write Go. It says where the
catalogue lives, that the description field is generated and not to be
translated, that a placeholder has to stay spelled the way it is, and that a
language may carry more plural forms than English does.

It also says the thing that would waste the evening: the window does not offer
a language switch yet, so a contributed catalogue ships and English is still
what it answers in. Saying so is the point of the section.

FOUR EXISTING GUARDS NOW READ IT, rather than it getting one of its own:

  - englishFiles, so ASCII only, flat hyphens and no semicolons.
  - TestTheInstallInstructionsCarryTheBuildTags. A guide telling somebody to
    build without the tag hands them a binary whose AVIF encoder reads past the
    end of a buffer.
  - TestTheBuildFloorIsThePinnedToolchainAndTheDocumentsSaySo, renamed from
    ...AndTheReadmeSaysSo because it is no longer only the readme. Three copies
    of the minimum Go version already existed and were guarded. A fourth
    without a guard would be the one that rots.
  - TestNothingThatDirectsAPersonPointsAtAnotherProject. These files get written
    by copying one from another project, and a link left pointing at the old one
    reads perfectly. That is not hypothetical here - it is what the guard was
    written for.

Two of those took a shared list of the documents that teach somebody how to
build, and the third took a filename parameter, so none of them names README
twice.

Four mutations, all caught: the tag dropped from the build command, a Go
version go.mod does not admit, an issue link pointing at the sibling project,
and a semicolon.

No changelog entry. That file is for changes somebody running tfg would notice,
and this is not one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit 3061f99 into main Sep 7, 2026
18 checks passed
@donislawdev
donislawdev deleted the docs/contributing-guide branch September 7, 2026 17:17
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.

1 participant