Forum teuk.org

🧩 MB678-IV-A — Give Partyline Plugin Commands Their Own Spellbook Without Changing the Incantations

in Mediabot · started by TeuK · 3d ago

TeuK · 3d ago

MB678 continues the progressive decomposition of Mediabot’s Partyline subsystem.

After separating transport, session/authentication, and dispatch responsibilities, MB678-IV begins extracting the remaining command implementations from the large Mediabot::Partyline module.

Rather than moving several thousand lines at once, this round deliberately starts with a coherent and self-contained command family: Partyline plugin administration and ScriptDryRun handling.

The goal remains the same as in the previous MB678 rounds: improve architecture without changing behaviour, protocol, command syntax, or the historical Mediabot::Partyline method surface.


🪄 What moved

MB678-IV-A introduces:

Mediabot/Partyline/Commands.pm

and moves the following methods into it:

_cmd_scriptdryrun
_plugin_info_text
_plugin_config_display_value
_cmd_plugins

Together, these methods cover the Partyline plugin-management and ScriptDryRun command surface.

They include responsibilities such as:

  • ScriptDryRun execution and presentation;
  • plugin inventory and status output;
  • plugin metadata formatting;
  • sidecar/plugin configuration display;
  • plugin metrics and related diagnostic information;
  • plugin action result formatting and safety handling.

The dispatcher remains unchanged.

It continues to invoke commands through the historical $self->_cmd_* method surface.

Mediabot::Partyline imports the extracted methods back from Mediabot::Partyline::Commands, preserving compatibility for existing runtime paths, tests, and callers.


🧱 Structural result

Before MB678-IV-A:

Mediabot/Partyline.pm : 5046 lines

After MB678-IV-A:

Mediabot/Partyline.pm             : 4196 lines
Mediabot/Partyline/Commands.pm    :  882 lines
Mediabot/Partyline/Dispatcher.pm  :  407 lines
Mediabot/Partyline/SessionAuth.pm :  676 lines
Mediabot/Partyline/Transport.pm   : 1012 lines

This removes roughly 850 lines from the parent Partyline module in one controlled extraction.

The Partyline architecture now clearly separates:

Partyline.pm
    remaining command implementations and core Partyline behaviour

Partyline/Commands.pm
    extracted plugin and ScriptDryRun commands

Partyline/Dispatcher.pm
    input routing and authenticated command dispatch

Partyline/SessionAuth.pm
    session lifecycle and authentication

Partyline/Transport.pm
    TCP / DCC transport and low-level input handling

MB678-IV-A intentionally does not attempt to move the entire remaining command set.

That keeps the extraction small enough to validate precisely and makes future command-family migrations easier to review.


🧪 Focused validation

A dedicated extraction contract was added:

t/cases/865_mb678_partyline_plugin_commands_extraction.t

The focused validation covered ScriptDryRun behaviour, plugin-management contracts, plugin metadata/configuration, action execution safety, plugin metrics, KV storage, and the new extraction boundary.

Result:

PASSED : 253/253

The historical Partyline method surface was also checked explicitly:

OK: Mediabot::Partyline->_cmd_scriptdryrun
OK: Mediabot::Partyline->_plugin_info_text
OK: Mediabot::Partyline->_plugin_config_display_value
OK: Mediabot::Partyline->_cmd_plugins

This confirms that callers do not need to know that the implementation moved.


🧩 Contract trap and fix

The first fast run exposed one remaining source-location assumption:

FAILED : 1/5665

The affected test was:

644_mb429_shared_truncate_utf8.t

It verified the UTF-8-safe truncation used for action text by reading only:

Mediabot/Partyline.pm

The relevant ScriptDryRun code now legitimately lives in:

Mediabot/Partyline/Commands.pm

while other UTF-8 truncation behaviour checked by the same test remains in the parent module.

The contract was therefore updated to inspect:

Partyline.pm + Partyline/Commands.pm

No production code was changed.

Targeted result:

PASSED : 14/14

This was another example of test architecture catching up with a deliberate source reorganization rather than a runtime regression.


🛡️ Security audit

The security audit remained completely green after the command extraction.

Final result:

Verdict: GO — all 11 security invariants hold.

The preserved guarantees include:

  • shell-safe external command execution;
  • protection against option injection;
  • CR/LF/NUL neutralisation on IRC output;
  • single-instance process locking;
  • HTTP download caps;
  • authentication throttling on both IRC and Partyline paths.

The new Commands.pm boundary did not weaken any security invariant.


🔌 Real runtime validation

The development service restarted successfully:

mediabot@dev.service
Active: active (running)

The Partyline listener remained available on:

0.0.0.0:23456

A real TCP login smoke test still produced:

Mediabot Partyline

Please enter your nickname.

Enter your password.

with:

RC_SMOKE=0

The service journal showed no obvious runtime errors after restart.

The extracted methods also remained visible through the original Mediabot::Partyline API, confirming that dispatcher-to-command calls continue to resolve through the historical surface.


⚡ Fast suite

After the UTF-8 source contract was updated:

PASSED : 5665/5665  (64s)

No fast-suite regression remained.


🏰 Full suite

The complete regression suite passed:

PASSED : 14577/14577  (207s)

This validates the extraction against the entire current Mediabot test surface.


🧠 Why this matters

The previous MB678 rounds removed transport, authentication/session management, and routing responsibilities from the parent Partyline module.

MB678-IV-A now begins removing the final major responsibility still concentrated there: command implementation.

The important part is not merely reducing line count.

The new boundary creates a safer migration path.

Instead of treating all Partyline commands as one enormous block, command families can now be extracted progressively into Partyline::Commands while preserving the same external behaviour after each round.

That gives each migration:

  • a bounded responsibility;
  • focused tests;
  • explicit source contracts;
  • runtime validation;
  • full regression coverage;
  • a clean rollback boundary.

The first family chosen — plugin administration and ScriptDryRun — was particularly useful because it exercises complex command behaviour, configuration inspection, plugin metadata, action processing, and UTF-8-safe output handling.

Passing the full suite after this move provides strong evidence that the Commands.pm architecture is viable for the remaining Partyline commands.

No Partyline protocol changed.

No command syntax changed.

No command was removed.

No historical method surface changed.

Only the location of the implementation changed.


📦 Commit

Version : 3.4dev-20260820_170611
Commit  : 9914aa8
Branch  : master

🧩 Give Partyline Plugin Commands Their Own Spellbook Without Changing the Incantations

Commit summary:

21 files changed
996 insertions
868 deletions

New files:

Mediabot/Partyline/Commands.pm
t/cases/865_mb678_partyline_plugin_commands_extraction.t

The commit was successfully pushed to GitHub.


🧩 The spells still sound exactly the same. They simply have a proper spellbook now.

You must be logged in to reply.