MB678 reaches its final command-extraction round with a deliberately isolated security boundary.
This round moves the two privileged Partyline controls:
_cmd_eval
_cmd_die
out of the historical Mediabot::Partyline parent and into a dedicated module:
Mediabot::Partyline::Privileged
This is intentionally not another addition to the already large Partyline::Commands module. .eval and .die have a different risk profile from ordinary operator commands: one executes Perl code under strict guards and watchdog/reaping logic, while the other can terminate the running process. They deserve an explicit privileged boundary.
The goal remains unchanged throughout MB678:
Move ownership, preserve behaviour.
No command route, privilege rule, confirmation path, event-loop behaviour, or historical method name was changed.
The following physical implementations moved from:
Mediabot/Partyline.pm
to:
Mediabot/Partyline/Privileged.pm
Methods:
_cmd_eval
_cmd_die
The historical API remains available through:
Mediabot::Partyline->_cmd_eval
Mediabot::Partyline->_cmd_die
because the dedicated module exports the methods back into the parent package.
Privileged.pmPutting these methods into Commands.pm would have worked mechanically, but would have weakened the architecture.
_cmd_eval contains security-sensitive and lifecycle-sensitive behaviour around:
permission guards
confirmation
forking
watchdog timing
non-blocking child reaping
output limits
process isolation
error handling
_cmd_die is equally special because it deliberately controls process termination.
The resulting ownership is therefore explicit:
Partyline::Commands
ordinary Partyline commands
Partyline::Privileged
privileged process / code-execution controls
That distinction is useful for future review, hardening, and security audits.
After IV-O:
Mediabot/Partyline.pm : 440 lines
Mediabot/Partyline/Privileged.pm : 388 lines
Mediabot/Partyline/Commands.pm : 4529 lines
Mediabot/Partyline/Dispatcher.pm : 407 lines
Mediabot/Partyline/SessionAuth.pm : 676 lines
Mediabot/Partyline/Transport.pm : 1012 lines
Most importantly, Partyline.pm now contains exactly five physical implementations:
new
get_port
_runtime_status_path
_runtime_status_payload
_write_runtime_status
There is no longer a physical _cmd_* implementation in the parent.
This is the architectural milestone MB678 was aiming for.
Because several historical tests intentionally inspect Partyline source ownership, IV-O updated the relevant source contracts rather than pretending the implementation still physically lived in the old file.
Updated contracts include:
105_partyline_eval_enabled_guard.t
120_partyline_eval_watchdog_uses_usleep.t
531_mb309_partyline_eval_nonblocking_reap.t
825_mb645_update_systemd_contract.t
870_mb678_partyline_karma_commands_extraction.t
872_mb678_partyline_reload_commands_extraction.t
873_mb678_partyline_network_stats_commands_extraction.t
874_mb678_partyline_irc_control_commands_extraction.t
875_mb678_partyline_ai_commands_extraction.t
876_mb678_partyline_runtime_diagnostics_commands_extraction.t
877_mb678_partyline_channel_moderation_commands_extraction.t
878_mb678_partyline_antiflood_commands_extraction.t
879_mb678_partyline_remaining_standard_commands_extraction.t
A new dedicated contract was added:
880_mb678_partyline_privileged_controls_extraction.t
Both historical entry points remained callable through Mediabot::Partyline:
OK: _cmd_eval
OK: _cmd_die
Result:
2/2
The dispatcher therefore does not need a new routing model and existing callers remain compatible.
The IV-O focused group covered the privileged-control contracts plus the recent MB678 extraction boundaries.
Result:
PASSED : 437/437 (5s)
No targeted regression was found.
The reviewed fast lane was then run with the MB679 progress display:
perl t/test_commands.pl --fast --progress
Result:
Selected: 323 of 763 discovered test file(s)
[====================] 100% [323/323 files | 5982 tests]
PASSED : 5982/5982 (65s)
The development instance was restarted after the extraction.
Result:
mediabot@dev : active
Partyline continued listening on:
0.0.0.0:23456
The real TCP smoke path returned:
Mediabot Partyline
Please enter your nickname.
Enter your password.
Result:
RC_SMOKE=0
The service journal showed no obvious fatal/runtime loading error.
The security audit remained completely green:
RC_AUDIT=0
Verdict: GO β all 11 security invariants hold.
That result matters especially for this round because the code being moved is explicitly privileged.
The full suite was run after targeted, fast, runtime, and security validation:
perl t/test_commands.pl --progress
Result:
[====================] 100% [763/763 files | 15109 tests]
PASSED : 15109/15109 (212s)
No follow-up production fix was necessary.
Version : 3.4dev-20260822_042704
Commit : fd0b4d3
Branch : master
π Give Partyline Privileged Controls Their Own Restricted Section Without Changing the Keys
Commit result:
17 files changed
570 insertions
416 deletions
New files:
Mediabot/Partyline/Privileged.pm
t/cases/880_mb678_partyline_privileged_controls_extraction.t
The commit was successfully pushed to GitHub.
IV-O completes the command extraction phase.
The parent now owns only:
construction
configured port access
runtime-status JSON publication
historical facade/import surface
public line-size compatibility constant
A fresh post-commit snapshot confirms that exact state.
The final MB678 task is therefore not another command extraction.
It is a boundary-closure pass:
remove stale dependencies left in the historical parent
move any dependency to its real owner when required
remove obsolete extraction tombstones/comments
add one final architectural boundary contract
validate targeted + fast + runtime + security + full
commit closure
No behaviour should move during that closure.
At the beginning of MB678, Partyline.pm was a large multi-responsibility module.
At the end of IV-O, it has become a small facade/core whose responsibilities can be explained in a few lines.
That is a much stronger stopping criterion than chasing an arbitrary file-size target.
The goal was never to make Partyline.pm disappear.
The goal was to make it obvious why every remaining line belongs there.
π The Restricted Section has its own door now β but the old keys still open exactly what they opened before.
You must be logged in to reply.