Repository navigation
Hand edit a generated file on purpose and prove the build objects - #34
Merged
Merged
Conversation
Two claims hold this repository up. No number in a lesson is typed by a person, and no table in a blueprint is transcribed by one. Both are enforced by regenerating the file and comparing it against what is committed, so both are exactly as true as that comparison is, and the comparison had never been tested. xray check --selftest copies a real lesson and a real blueprint, hand edits the generated files five ways, and requires the check to object to each one by name. Two more cases change nothing and have to pass. Those two controls found a real bug on their first run. The boss fight section of a lesson page embedded the lesson's path relative to the current working directory, so xray check produced a different page depending on where it was run from, and failed with a diff nobody could explain. It is now relative to the top of the repository.
This was referenced Sep 5, 2026
Closed
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 third of the four M1 blocking gates, and half of the exit criterion for this milestone.
What was untested
Two claims hold this repository up.
Both are enforced the same way. The tool regenerates the file, compares it against what is committed, and fails on any difference. Both are therefore exactly as true as that comparison is, and nothing had ever checked that the comparison works.
That is the same criticism I made of the citation gate in #31 and the assertion checker in #33, and it applies here more sharply, because a comparison that always passed would look precisely like a repository where nobody has ever hand edited anything. Nobody would find out which of the two this is until a reader noticed a page saying something the program does not.
The test
xray check --selftestcopies a real lesson and a real blueprint out of the tree, breaks each copy in one specific way, and runs the ordinary check over it.The tamper for a number is to find the first digit in the file and bump it, which is the smallest edit that is still a lie, and it is the exact thing the first claim above says cannot survive. Each refusal is asserted for the message as well as the verdict, so a check that failed for some unrelated reason does not count as a pass.
The two cases that change nothing are the reason the other five mean anything. A harness that failed on everything, including work that is correct, would report a clean sweep without them.
Which is how the bug turned up
The control failed on its first run, and it was right to.
The boss fight section of a generated page names the lesson so the reader can copy the grader command, and it was computing that path relative to the current working directory. So the page depended on where the tool was run from. Here it is before this change, on a clean checkout with nothing edited:
A red build, on correct work, with a diff that makes no sense to whoever is looking at it. It never fired in CI because every job happens to run from the repository root, which is the sort of luck that runs out on the day somebody adds a job that does not.
The path is now taken relative to the top of the repository, found by walking up for
ClrXray.slnx. Anything that goes into a generated file has to be relative to that rather than to the working directory, andFiles.Rootsays so in a comment for the next person to put a path in a page.Worth being plain about the order here: the five tamper cases were all passing while this bug was live, and they were passing for the wrong reason. Every one of them was detecting the path difference rather than the tamper. The control is the only thing in this pull request that could have told me that.
Also in here
The self test builds its copy under a marker file at a synthetic repository root, so the copy keeps its position in the tree and renders the same page the original does. That is not a workaround for the bug above, it is what makes the cases test the tamper rather than the move.
A new
tamperjob runs it onubuntu-latest.Checked locally
Also checked that
check lessonsnow passes fromdocs/as well as from the root, which is the thing that was broken.One thing this does not fix
mainhas no branch protection, so none of these gates is blocking in the sense the milestone means. A pull request with every check red can be merged today. That is a repository setting rather than code, and it is the next thing I am doing.