'silent-lwedit edits a page of this wiki without touching its last-modified date. For cosmetic corrections only—a typo, a stray where a was meant, a category tag: the things a bot rights in passing.
Written with Claude Fable 5 on 8 August (2026). Version 1.5.
The date a page was last modified means something on this wiki: when some important activity last took place on it—not when a bot passed by to trade quotes or right a typo. A cosmetic correction should leave that signal alone while still being recorded. Creating a page or adding a section is real activity and must move the date, which is why this tool refuses a page that does not exist.
The new text is written as a revision carrying the same timestamp as the page's current top one, through maintenance/importDump.php—the one import path that stacks no bookkeeping revision on top (see llw2lw for that story). The footer keeps its date; the page history still gains the revision with its honest summary, so nothing is hidden—it just does not claim to be activity. Link tables are refreshed with a revisionless action=purge&forcelinkupdate, and every write is verified by reading the page back: importDump happily prints Done! after mangling a malformed page, so its word is never taken for it.
A hand edit racing the tool is safe by construction: it carries a newer timestamp, so MediaWiki keeps it current and the silent revision files into history beneath it—reported as conceded, nothing clobbered.
importDump gives a revision the top only when its stamp is not older than the one already there—equality wins, which is the whole of the same-timestamp trick above. An --at in the past therefore files quietly into history instead, beneath whatever is current. That is the honest outcome when a later local edit has already moved the page on, but the verification, which only ever reads the current text, still calls it FAILED: it did file, and the check has not caught up.
silent-lwedit -e "s/'''/''/g" "Template:Delvalle12a" # sed-style, in place
silent-lwedit -e "s/foo/bar/gi" --category "Articles" # every page of a category
silent-lwedit --dry -e "s/.../.../" Some page # diff only, write nothing
silent-lwedit -f new.txt "Title" # whole page from a file
silent-lwedit -p pairs.tsv # many pages, one import
silent-lwedit -f back.txt --at 2026-08-21T19:50:03Z Fabrice
-e takes sed's s/pattern/replacement/flags (g, i, any delimiter, several -e chain); -s sets the edit summary. Always --dry first.
--at files the revision at a moment you name instead of at the page's current one, for the one write on this wiki that is not a cosmetic correction: putting back an edit made at laussy.org and then destroyed by the sync (see syncloss and llw2lw). Give it its own -s as well—the default summary calls the write a cosmetic edit, which this is not.
action=edit does, so a trailing newline survived where the parser would have trimmed it—and sitting after a </noinclude> it was transcluded, giving every * {{key}} bullet a blank line and shattering author-page lists. The tool now trims as the parser would, and a newline-only difference counts as a write.A silent edit never reaches Recent Changes—that is its point—so llw2lw would never learn the page changed and the online copy would silently drift. Every silent write therefore records its title in ~/.silent-lwedit-manifest, which llw2lw (2.7.0) folds into every run automatically and clears as titles land online. And since llw2lw (2.8.0) mirrors timestamps, an import at an equal timestamp becoming the current revision, a correction silent here is silent on laussy.org too.
The script lives in ~/bin/silent-lwedit (python; credentials from ~/.syncy, shared with bib2wiki).