* chore: write the site name as evomedia.net, lowercase
The name is a domain and is written as one. Script headers, the README,
CHANGELOG and elevator pitch, their .txt twins, and the site page --
matching the same sweep in the private evo.scripts so the mirror does not
drift.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: refresh CHECKSUMS.txt for the lowercase sweep
Every script's header changed, so every hash did. The repo's own
Checksums test caught it -- which is what it is for.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Defers to the org policy for how to report and covers what is particular to a
repository that is a sanitised mirror: the most valuable report here is not a
crash, it is something REAL that should not be here - a credential, an internal
hostname, an operator path, an identifier naming a private project. Mail those
rather than filing an issue, because a public issue about a leaked secret
publishes it a second time.
It also says what the automated check is and is not. The sanitisation suite is
a DENYLIST: it proves the absence of known patterns, not the absence of
secrets. Green tests are why a human report is still worth sending.
And the ordinary warning for what these actually are - automation that
archives a tree, uploads it, rebuilds containers and restarts services. Read
before running, nothing here is a sandbox, the config is yours to replace.
TWINS ARE NOW DISCOVERED, NOT LISTED. PAIRS was hand-kept and two files had
outgrown it: ELEVATOR_PITCH.md and TOKEN_SAVINGS.md had no twin at all. Adding
a document and remembering to add it to a list are two acts, and the second is
the one that gets skipped.
The Pester test had the same shape in reverse - it scraped PAIRS out of the
generator's source, so it could only prove the list was self-consistent and a
document nobody listed was invisible to it. It now asks the REPOSITORY what
markdown it has. Proven by deleting SECURITY.txt and watching two tests fail.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
The changelog said nothing had been released since 1.0.0. Twenty-two builds
had shipped. Twenty-one entries sat under "## Unreleased" in a file with
exactly two headings, so a reader at any tag found no section for the version
they were holding.
Which release carried which entry is DERIVED, not guessed: for every line in
the region, the commit that introduced it, then the earliest tag containing
that commit. That yields seven releases - .22, .21, .20, .19, .14, .8 and .0.
No entry text changed. A verification pass compares the multiset of
non-heading lines before and after and refuses to write if anything was lost,
gained or duplicated; entries move under their release, so it compares as a
multiset rather than in order.
CHANGELOG.txt was kept BY HAND and drifted the moment the .md was
reorganised, which is the failure the plain-text-twin rule exists to prevent.
readme_txt.py becomes plaintext_twins.py and renders every pair. It also
drops <!-- --> markers, invisible in markdown and stray punctuation in a text
file - that is the whole of README.txt's diff.
The --check that keeps twins honest was never run. readme_txt.py shipped one
and its docstring claimed "the test suite runs --check"; nothing invoked it,
so a twin could disagree with its markdown indefinitely.
tests/PlainTextTwins.Tests.ps1 runs it.
That test skipped on its first run while claiming to pass: -Skip is evaluated
during DISCOVERY, before BeforeAll, so the python lookup left the flag $null.
Resolved in BeforeDiscovery, and when python really is absent the result is
INCONCLUSIVE rather than a green tick for a check that never happened.
Mutation-checked: appending one line to CHANGELOG.txt fails "every twin is in
sync with its markdown", and only that test.
tests: 243 passed, 0 failed, 1 skipped (the no-python reporter, correctly).
The mirror's deploy pair had drifted ~280 lines behind: it lacked the
transactional .env preserve/restore (an interrupted deploy could destroy
server-side env files), the stderr-flattening step wrapper (a successful
deploy reported failure and skipped its own verification), and the
verification rework (channel re-picked every retry, edge only with a Host
to route by, verify.timeoutSeconds, honest split of "stale build" vs "no
channel answered").
The sync is byte-faithful to the private tree except where the mirror's
own Sanitization suite demands otherwise - and it caught the first copy:
three failures for private project names, a private domain, and a
private-only script name that rode along in comments. Each war story keeps
its lesson and loses its cast, per the convention already in the file
("EvoCivilCode: deploy/" was already published as "(deploy/, infra/,
...)"). That suite going red on an unsanitized copy is exactly what it
exists for.
Also in this change:
- tests/VerifyPlan.Tests.ps1 - the channel-selection rules are pure
functions and Pester pins them (no domain => no edge attempt; the PS 5.1
one-element-unroll trap). First verification tests in the mirror.
- README: the verify block now documents viaProxy/upstream (they shipped
in the docker-network read but were never in the README),
timeoutSeconds, and the channel order with why it re-resolves per retry.
- README.txt: generated plain-text twin, via scripts/readme_txt.py
(vendored from the fleet's reference implementation; the file is
generated, never edited by hand).
- CHANGELOG.md/.txt: entries merged into the existing Unreleased sections.
CHECKSUMS.txt refreshed (42 entries). Pester: 240 passed, 0 failed.
Both synced files parse clean.
Observed, untouched: the Unreleased section carries duplicate "### Fixed"
headings from earlier appends; folding them risks reordering entries whose
prose references their neighbours, so it is left for the next release cut
(zbump #110 rolls Unreleased into the version being cut).