helloworld.html always contains exactly one deliberate misspelling. When somebody fixes it, a
maintainer plants the next one, and the person who fixed it gets a row in the chain below.
This file is the ledger. It exists so the relay cannot quietly stop: CI reads it, and main
goes red the moment a seed has been fixed and not replaced. A forgotten relay is a build
failure rather than a slow disappointment for the next person who comes looking.
number: 6
file: site/helloworld.html
sha256: 89052ba0b168f2c25e6024e7ac99ede70ff2fd9a6795925e97cb888e80defef3
planted: 2026-10-18
The word itself is stored as a SHA-256 hash rather than in plain text, because writing it here would hand away the puzzle to anyone who reads the repository before the page.
This is deliberately weak protection. A hash of an ordinary English misspelling falls to a
wordlist in seconds, and that is fine: if you would rather solve this by hashing a dictionary
than by reading a paragraph, you have done something more interesting than finding a typo, and
we would like to see that script. Send it as a pull request to examples/.
A seed goes in ordinary prose, in a sentence a person reads. It may never sit in any of these, because a “typo” in one of them is a defect and not a game:
<code>, <script> or <style>SHIPLEY_*_V1 publisher markertools/validate_site.py requirestools/validate_seed.py enforces the first four mechanically. The last two are judgement, so
read the page before you plant.
Newest first. Each row is a real merged pull request against a live page.
| # | Misspelling | Found and fixed by | Merged |
|---|---|---|---|
| 5 | photogrephy |
@Kira-Saints | 2026-10-18 |
| 4 | famliy |
@tadaokatzuki | 2026-10-15 |
| 3 | buisness |
@O1sumitkumar | 2026-10-06 |
| 2 | catagory |
@aipd506 | 2026-10-02 |
| 1 | recieve |
@Jah-yee | 2026-09-30 |
The full cycle, including who can do which half, is in docs/MAINTAINING.md.
After merging a fix, plant the next seed in the same commit range, not “later”:
python3 tools/plant_seed.py --credit @their-handle --fixed recieve \
--correct permanent --misspell permenant
That rewrites the page, updates the block above, moves the fixed seed into the chain, and prints the publish command. Then run the publisher so the live page matches the repository, because a merged fix that is never published makes a liar out of the page.
tools/validate_live_seed.py checks that last step actually happened. It fetches the published
page and fails if the page does not carry the seed named above; .github/workflows/live-seed.yml
runs it hourly. validate_seed.py --require-live cannot do this, because it reads the
repository file and never the network. That gap is not hypothetical: seed 2 stayed on the live
page for a day after it was fixed and credited, and seed 3 for six days, with a green build the
whole time.
The publisher refuses to run from a clone that does not match origin/main, which is the other
half of the same problem. A stale checkout has a stale ledger too, so the page and the file it
is checked against agree with each other and a seed comparison cannot see anything wrong. Only
the remote can.