A deployment chronicle from the Ministry corridors of Mediabot v3
Commit: 12d60d5
Version: 3.6dev-20260921_110437
Branch: master
#test 🔮The quotes-v3 pilot had passed every preliminary inspection. Its permissions were complete, its five commands were registered, its failure ledger was spotless, and the channel policy for #test remained safely in observe mode.
Then an anonymous traveller attempted a simple incantation:
#q add …
Instead of entering the quote vault, the message met a database ward:
Database error while adding quote.
The new plugin had not failed. Under observe, its output was deliberately hidden and the established command handler remained visible. That legacy path reached the same old curse as the new write service: both represented an anonymous author as id_user = 0.
The QUOTES.id_user column, however, was guarded by a foreign key to USER.id_user. There was no lawful user numbered zero. The vault rejected the offering exactly as its constraints required.
MB755 gives anonymous quotes a proper identity: no fabricated account, no sentinel value, and no loophole in the foreign key. An anonymous author is now stored as SQL NULL.
The change was made on both sides of the passage:
Mediabot/Quotes.pm now writes NULL for anonymous authors in the established command path.Mediabot/Plugin/QuoteWriteServiceV3.pm applies the same rule through the API v3 write service.USER.id_user value.QUOTES.id_user as a nullable unsigned BIGINT.ON DELETE SET NULL and ON UPDATE CASCADE.That final rule matters: if a user account is removed, the quote survives while its attribution becomes anonymous. The words remain in the archive; only the vanished identity is released.
Existing installations receive the replayable migration:
install/migrations/20260921_quotes_anonymous_author.sql
Its stored procedure does more than alter a column and hope for the best. It inspects the existing schema, rejects unsafe or unfamiliar shapes, rebuilds the canonical constraint, converts zero and orphaned author references to NULL, and verifies the finished contract.
The resulting vault law is explicit:
| Property | Final value |
|---|---|
| Type | BIGINT UNSIGNED |
| Anonymous value | NULL |
| Foreign key | QUOTES.id_user → USER.id_user |
| On user deletion | SET NULL |
| On user ID update | CASCADE |
| Zero or orphaned authors | None |
The migration is idempotent, so a second owl may safely deliver the same parchment without reshaping the vault again.
The first complete test run exposed one final moving staircase. The migration contained a deliberate durable UPDATE, but Mediabot Doctor did not yet possess a model for proving that mutation safe. It therefore failed closed, as designed.
MB755 R2 added the narrow, read-only quote_author_integrity observable to tools/mediabot_doctor.pl. Doctor can now certify this exact migration only when all of the following are true:
QUOTES.id_user is nullable BIGINT UNSIGNED;DELETE SET NULL and UPDATE CASCADE;This is not a blanket permission for migration-time updates. Any other unrecognised durable mutation remains indeterminate and continues to stop validation.
The operational examination was performed through a temporary Partyline Owner account, removed immediately after use.
The quotes-v3 package was loaded with only its declared capabilities:
data.quotes.read
data.quotes.write
irc.reply
irc.notice
It remained enabled under the #test policy observe, which produced the expected shadow decision: the plugin executed, its output stayed hidden, and the visible migration fallback remained in command.
The decisive live probe then crossed IRC:
IRC #test: #q add MB755-… anonymous NULL probe
mediabotv3: done. (id: 59)
The database confirmed that quote 59 carried id_user = NULL. The proof quote was deleted cleanly, the temporary Partyline account was removed, and the plugin reported:
ready (operational);5/5;0;0.No test quote and no temporary identity were left haunting the castle.
The final patch crossed every required gate:
| Examination | Result |
|---|---|
| MB755 targeted tests | 224/224 passed |
| Fast validation lane | 7,618/7,618 passed |
| Complete suite | 20,094/20,094 passed |
| Complete-suite files | 991/991 passed |
| Development service | Active |
The complete suite took 143 seconds and finished without a single failed assertion.
The finished work was committed and pushed to master as:
12d60d5 MB755: grant anonymous quotes a lawful vault identity 🪶🗝️
The ledger records 24 changed files, 494 insertions, and 36 deletions. It includes the production fixes, fresh-install schema, replayable migration, Doctor observable, API and architecture documentation, changelog entries, and the new anonymous-identity regression suite.
MB755 closes the anonymous-write defect without weakening attribution, foreign-key integrity, or migration scrutiny. Legacy and API v3 quote writes now agree on the same lawful representation, and account deletion no longer threatens the quote archive.
The quotes-v3 pilot deliberately remains in observe on #test. Promotion to on is a separate operational decision, to be made only after the observation window has supplied enough evidence. For now, the new spell runs in shadow, the old voice stays audible, and the vault finally accepts anonymous wisdom without pretending that nobody is user zero. 🪶✨
You must be logged in to reply.