Commit: 7dc9733
Version: 3.4dev-20260817_044354
Mediabot has gained a new kind of spell: one that does not change anything.
Instead of restarting services, repairing files, changing configuration, touching MariaDB, or trying to be clever on behalf of the operator, Mediabot Doctor observes the real installation and reports what it can prove.
The first two rounds are now committed and pushed.
mediabot_doctor.plThe new tool lives here:
tools/mediabot_doctor.pl
and is tracked executable by Git.
A typical run looks like:
./tools/mediabot_doctor.pl --root /home/mediabot/mediabot_v3 --conf /home/mediabot/mediabot_v3/mediabot.conf
Doctor is deliberately read-only.
It does not modify configuration, write to MariaDB, apply migrations, restart or stop Mediabot, edit systemd units, fetch or modify Git state, or repair deployment trees.
Its job is to tell the truth about the instance it is examining.
Doctor separates three responsibilities:
collection
↓
evaluation
↓
rendering
The probes collect facts. The evaluator decides what those facts mean. The renderer presents the result as text or JSON.
A probe failure must not crash the diagnostic tool or silently become an OK.
Doctor uses explicit states:
OK
INFO
WARN
FAIL
UNKNOWN
and an overall result:
READY
DEGRADED
UNSAFE
A fact that cannot be established remains UNKNOWN with a reason. Doctor does not invent a reassuring answer.
Configuration inspection distinguishes required, optional and defaulted values.
Secret values are deliberately not copied into Doctor’s internal fact structure.
Doctor may report:
12 secret key(s) present
but not their contents.
Doctor does more than check whether a PID file contains a number.
It verifies:
PID exists
→ process is alive
→ process command line belongs to the inspected Mediabot tree
→ running process uses the inspected configuration
This protects against stale or recycled PID files and against confusing two Mediabot instances launched from the same source tree with different configuration files.
The filesystem probe currently checks the important local pieces of an installation, including the main program, VERSION, module directory, sample configuration, instance configuration, PID file, log file, plugin data, project directory, parent directory and legacy achievement JSON state.
It also understands symbolic links and runtime permissions.
One useful bug was found during real-world testing.
The development configuration is:
mediabot.conf
→ mediabot.conf_20260617_1305
with:
0660 mediabot:mediabot
An early Doctor version called this too permissive.
That was wrong.
The group is a private runtime group, so the final Doctor checks the actual runtime identity and group membership before deciding whether group permissions are dangerous.
The final result is correctly:
config_file present and usable
configuration permissions 0660 use private runtime group mediabot
rather than a false warning.
Another real installation exposed a subtler issue.
One older deployment has:
mediabot.pl mode 664
At first, Doctor reported that as a fatal error.
But the service actually launches the bot as:
/usr/bin/perl /path/to/mediabot.pl
In that execution model, the script must be readable; the kernel does not require its executable bit.
Doctor now distinguishes:
direct execution + no executable bit
→ FAIL
execution through Perl + no executable bit
→ WARN
unknown launch mode + no executable bit
→ WARN
The warning remains useful as a packaging observation without incorrectly claiming that the currently running service cannot work.
One of the most important design corrections was refusing to treat all systemd signals as equivalent.
Doctor keeps these separate:
runtime_manager
safe_update_marker
actual_systemd_contract
They answer three different questions:
MEDIABOT_SYSTEMD_UPDATE_SAFE=1?For the MB645 contract this includes:
Restart=always
ExitType=cgroup
SuccessExitStatus=75
RestartPreventExitStatus=75
Doctor can therefore detect disagreement instead of assuming one signal proves the others.
A particularly useful bug appeared when running only selected domains:
--domain filesystem --domain systemd --domain updater
The first implementation skipped the runtime probe entirely because it was not requested for display.
That meant filesystem and systemd lost facts such as the observed PID, runtime UID, runtime groups and launch mode, and produced false diagnostics.
The corrected model separates:
domains requested for display
from:
probes required internally as dependencies
So Doctor may silently collect runtime facts while displaying only the requested domains.
Filtering output no longer changes the reality being diagnosed.
Doctor understands that not every Mediabot installation is a Git checkout and not every instance uses the built-in updater.
It can report a non-Git deployment as a supported style rather than an error.
It also understands deployment families.
For an instance rooted at:
/home/mediabot/mediabot3
Doctor recognises:
mediabot3.old.YYYYMMDD_HHMMSS
as the same deployment family while explicitly ignoring sibling families such as:
mediabot_v3.*
A real validation produced:
deployment family 'mediabot3' isolated
11 archive(s)
2 sibling-family archive(s) explicitly ignored
application root is not a Git checkout (supported deployment style)
Real-world testing exposed another architectural lesson.
A service can legitimately have an older systemd lifecycle contract when the built-in updater is not applicable to that deployment.
Therefore Doctor must not blindly say:
not MB645
→ UNSAFE
The evaluator considers updater applicability when assigning severity.
The intended logic is:
built-in updater applicable
+ MB645 contract missing
→ unsafe
built-in updater not applicable
+ older coherent service contract
→ informational
safe-update marker claims MB645 support
+ real unit does not satisfy it
→ unsafe regardless
This prevents Doctor from turning “different deployment model” into “broken installation”.
For Git installations, Doctor can inspect working-tree changes and cached upstream divergence without fetching from the network.
A non-Git production tree is simply reported as a supported deployment style.
No fake failure.
Two dedicated test files now protect the implementation:
t/cases/828_mb647_doctor_core_local_probes.t
t/cases/829_mb648_doctor_systemd_updater.t
During development they caught several real problems, including invented configuration keys, invalid domains returning RC=0, non-existent roots returning RC=0, invalid fact levels silently degrading to INFO, runtime/config identity ambiguity, false config permission warnings, probe dependency bugs, incorrect executable-bit assumptions and systemd/updater severity without deployment context.
The final complete Mediabot suite passed:
PASSED : 13118/13118
RC=0
The committed rounds cover:
Runtime implemented
Config implemented
Filesystem implemented
systemd implemented
Updater implemented
Database next round
Migrations next round
The future database probe remains constrained by the same rule:
read-only means read-only.
It will not call a constructor that can terminate the whole diagnostic process on connection failure, and it will not invent a second schema-drift implementation.
Schema comparison will remain delegated to the existing authoritative tooling.
Migration history will also be reported honestly: because Mediabot currently has no migration ledger table, Doctor can report observable effects as:
observable_effect_present
observable_effect_missing
indeterminate
but must never pretend it can prove historical execution when no source of truth exists.
The most useful result of Mediabot Doctor so far has not been a pretty health screen.
It has already forced several assumptions to prove themselves against real installations.
During development we found cases where:
a private 0660 configuration was wrongly called unsafe
a filtered command changed the diagnostic result
a Perl-launched script was wrongly considered non-runnable
an old systemd contract looked dangerous without updater context
Those are exactly the mistakes a diagnostic tool must eliminate before people trust it.
No auto-repair. No magic wand waving behind the operator’s back. Just evidence.
7dc9733
🩺 Give Mediabot a Hogwarts Healer for Read-Only Diagnostics
Five files were committed, including the automatic VERSION update:
CHANGELOG.md
VERSION
tools/mediabot_doctor.pl
t/cases/828_mb647_doctor_core_local_probes.t
t/cases/829_mb648_doctor_systemd_updater.t
The spell has been pushed to GitHub.
Next stop: read-only database and migration diagnostics — still without changing the MariaDB schema.
You must be logged in to reply.