Forum teuk.org

⏳ Mediabot 3.4dev — House Hourglasses, Polyjuice Reloads and the Prince’s Plugin Cookbook 🧪📖🪄

in Mediabot · started by TeuK · 1mo ago

TeuK · 1mo ago

Mediabot v3 closes another major chapter of its 3.4 development cycle with a final round on the external script bridge.

This pass is about operational visibility, safe hot reloads and documentation that is tested as seriously as code.

The plugin system can now show its event cooldown windows, clear them without touching timers or counters, refresh its configuration without unloading, and teach every supported pattern through a dedicated cookbook.

⏳ The Four House Hourglasses

Event routes already had anti-storm cooldowns, but those windows were invisible to operators.

That is now fixed.

The partyline exposes:

.scriptdryrun events

It shows:

  • the configured event routes;
  • the cooldown duration;
  • observed and skipped event counters;
  • active cooldown windows by event and channel;
  • how long each window has left;
  • which windows are already ready again.

Example:

ScriptDryRun events:
  event_map: join=greet.pl,kick=kickwatch.pl
  event_cooldown: 60s
  observed_events: 7
  skipped_events: 3 (cooldown: 2)
  join #a: last=10s ago, cooling (50s left)
  join #b: last=500s ago, ready

There is also a controlled reset command:

.scriptdryrun clearevents

It clears cooldown windows only.

Routes remain configured.
Counters remain intact.
Timers remain armed.
No script is executed.

In Hogwarts terms: the House hourglasses can be turned over without dismissing the students, erasing the scoreboards or breaking the Time-Turners. ⏳

🧪 Polyjuice configuration reload

The script bridge can now refresh its configuration without unloading the plugin.

After reloading the main configuration file with the usual Mediabot command, the operator can run:

.scriptdryrun reload

The plugin then re-reads:

COMMANDS
ROUTES
SCRIPT
ACTION_MODE
ALLOW_IRC
APPLY_REQUIRE_SCOPE
EVENTS
EVENT_COOLDOWN
CONFIG_<route>

Event listeners are updated only when event routes actually change, preventing duplicate subscriptions.

The refresh also preserves the state that should survive:

  • counters;
  • event cooldown windows;
  • armed timers.

A timer already armed keeps the configuration snapshot it received when it was created. New commands use the refreshed configuration.

That is deliberate. The potion changes the plugin’s current appearance, but old Time-Turners keep the ingredients they were given. 🧪

🛡️ Final hot-reload hardening

One subtle edge case was caught during the final review.

Config::Simple can return a single fallback SCRIPT path as an array value. Initial plugin registration already normalized that value into a scalar path, but the new hot-reload path did not apply the same normalization.

Without the fix, a fallback command could receive an array instead of a usable script path after:

.reloadconf
.scriptdryrun reload

The final hardening makes registration and hot reload follow the same rule and adds dedicated regression checks.

Explicit ROUTES were never affected. The correction protects the fallback SCRIPT path.

No Polyjuice accident survives the test suite. 🛡️

📖 The Half-Blood Prince’s plugin cookbook

The bridge now ships with:

plugins/scripts/COOKBOOK.md

This is the practical companion to the main README: a “how do I do this?” guide built from the real examples.

Its recipes cover:

  1. the minimal protocol contract in Perl, Python and Tcl;
  2. argument validation and effective usage limits;
  3. strict parsing of untrusted input;
  4. the complete timer lifecycle;
  5. join, part, topic and kick event fields;
  6. staying silent when routed to the wrong event;
  7. per-route configuration with safe defaults;
  8. the limits enforced around external scripts;
  9. cross-references to the shipped examples.

The cookbook itself is protected by tests.

Every example it cites must exist.
Every shipped example must be documented.
The stated example count must match the directory.
Important rules are cross-checked against the source code.

It is not merely parchment. It is a tested contract. 📖

🧭 A complete plugin arc

This closes the Mediabot plugin arc that introduced and hardened:

  • channel-scope protection, including IRC status-message targets;
  • guarded timer actions;
  • timer visibility and cancellation;
  • join, part, topic and kick event routes;
  • anti-storm cooldowns;
  • event-window visibility and reset;
  • per-route configuration;
  • configuration snapshots across timers;
  • safe hot reload;
  • multi-language examples in Perl, Python and Tcl;
  • a tested cookbook and maintainer handoff.

The bridge remains deliberately strict:

  • events are opt-in;
  • output stays channel-scoped;
  • timer chains are blocked;
  • pending timers are capped;
  • cooldowns start at event acceptance;
  • nickname changes remain outside the event model because they do not have one unambiguous channel scope.

✅ Validation

Claude’s completed rounds reached:

10507/10507 tests passed  — event cooldown visibility
10538/10538 tests passed  — plugin hot reload
10579/10579 tests passed  — cookbook and arc closure

The final hot-reload hardening adds two dedicated regression assertions for fallback SCRIPT normalization.

No database schema change.
No secret handling change.
No mandatory live configuration change.

🧙 Summary

This round turns the external script bridge into something that is not only powerful, but operable and teachable.

Operators can see cooldown windows.
Testers can clear them safely.
Configuration can change without killing the plugin.
Existing timers keep deterministic snapshots.
Fallback scripts remain valid after reload.
Authors get a tested cookbook instead of scattered examples.

The castle now has visible hourglasses, controlled potions, annotated spellbooks and enough protective charms to keep the moving staircases from surprising the next maintainer. 🪄

You must be logged in to reply.