Forum teuk.org

🪄 Finite Incantatem — Clear Radio Portraits and Inches That Count

in Mediabot · started by TeuK · 2d ago

TeuK · 2d ago

Mediabot MB855–MB856 · 20 October 2026 · Coherent radio observations, restored inch syntax and finite conversion results.

Two more maintenance rounds follow the previous MB838–MB854 chapter. This time, the work concentrates on two everyday tools: reading the radio’s current state and converting units on IRC.

A radio summary could combine several different observations into one report. The conversion command could lose the inch unit while parsing its arguments, or announce a successful calculation ending in Inf. Both problems now have reproduced regressions and corrections, with complete host validation on teuk.org.

The latest checkpoint passed 26,433 tests across 1,140 files. The database schema remains unchanged. 📜

📻 MB855 — One observation for one radio portrait

Reading the radio’s state involved more requests than the resulting message suggested:

Reader Previous status requests Now
Primary-mount status 3 1
Radio summary 4 1

The old sequence fetched global server information, listener counts and mount details separately. A summary then fetched the detailed mount list again.

If the station changed between those requests, a report could combine an earlier server observation with later listener counts, another title and a different mount list. A failure on a later request could also discard a valid response already received at the start.

MB855 makes each aggregate read one status-json.xsl response, then derives all its views from that decoded document. Server information, selected title, listener counts and detailed mounts now belong to the same observation.

The moving portraits can keep moving; each report gets one frame. 🖼️

Fresh on the next call

This introduces no new cache. A subsequent call makes a fresh request, and standalone status, listener, mount and now-playing reads remain independent observations.

Existing behaviour is retained for configured primary-mount selection, fallback to the first sorted mount, explicit zero listeners, Unicode titles and the public result structures. HTTP failures, empty responses, malformed JSON and missing mounts remain visible errors. The next valid response can recover normally.

The change reduces redundant status traffic and prevents fields from different responses being stitched together. It does not create a transaction with the live stream or Liquidsoap.

Tested with a station that changes every time

The 84 new assertions include a real local HTTP endpoint whose station document changes on every request. They verify that each aggregate stays coherent, the next call sees a fresh document, and six public reader calls issue exactly six status requests.

Additional cases cover a healthy observation followed by an outage, single-source and multiple-source documents, Unicode metadata, zero listeners, mount selection and error recovery. The tests use their own local sockets and child process; they do not manipulate a production station.

📏 MB856 — Give the inches their place back

The conversion command supports an optional English separator:

!convert 100 km to mi
!convert 100 km in mi

However, its argument filter removed every token named in. That also removed the abbreviation for inches when it appeared as a source or destination unit.

An ordinary request such as !convert 12 in cm consequently lost a required argument and returned syntax help.

The parser now removes an optional separator only from the position between the two units in the four-argument form. Unit positions keep their meaning:

Command Result
!convert 12 in cm 12 in = 30.48 cm
!convert 12 in to cm 12 in = 30.48 cm
!convert 1 m in 1 m = 39.370079 in
!convert 1 m to in 1 m = 39.370079 in

Even !convert 1 m in in is unambiguous under that grammar: the middle in is the separator and the final in is the unit.

Mixed case and existing aliases such as inch remain supported. Successful channel conversions retain their normal public reply; private-context results return to the caller through the existing Context route.

🔢 MB856 — A successful conversion must have a finite result

The numeric review found two related problems.

First, an input such as 1e9999 could overflow during numeric conversion and still be reported as a successful result containing Inf.

Second, the calculation could overflow or underflow in an intermediate step, even when the final answer was representable. For example, converting 1e300 TB to TB first multiplied through the byte base unit. That unnecessary intermediate overflow turned an identity conversion into infinity. A very small milligram identity could similarly collapse to zero. Temperature formulas had comparable multiplication-before-division cases.

The correction makes three changes:

  • Validate numeric input: accept the supported signed decimal/scientific syntax and refuse malformed values, references or numeric characters Perl cannot parse correctly.
  • Require finite input and output: an overflow produces a bounded error instead of a successful pseudo-result.
  • Avoid unnecessary intermediate extremes: form the fixed unit ratio before scaling, and multiply temperature ratios directly rather than multiplying before division.

Large conversions that remain representable can therefore succeed. Unknown units and incompatible families still receive their existing descriptive refusals.

Errors remain private notices to the caller, and a refused conversion does not create a successful-conversion audit event. These checks retain ordinary floating-point precision and display formatting; they do not turn the command into an arbitrary-precision calculator.

Finite Incantatem, applied quite literally. 🪄

Arithmetic and delivery are both covered

The 255 new assertions cover large finite values, a subnormal identity, input/output overflow, invalid numeric syntax and ordinary conversions across all six supported families.

The command tests use the actual handler, conversion module and Context with captured bot output. They verify inch arguments in both positions, optional separators, aliases, case handling, public and private delivery, input limits and success logging only after a successful conversion.

🧪 The O.W.L. results

Both rounds passed their complete suites on teuk.org:

Round New regression assertions Focused lane Fast lane Complete suite
MB855 — radio observations 84 908 / 908 8,317 / 8,317 26,177 / 26,177
MB856 — conversion syntax and numbers 255 1,174 / 1,174 8,318 / 8,318 26,433 / 26,433

Together, these rounds add four regression files containing 339 new assertions. The latest full run covers 1,140 test files. All 37 source security invariants pass, and the generated command inventory matches the source catalogue.

The fast lane remains a development check and does not replace the complete suite. The source packages retain isolated previews, private backups and restoration after a failed required check. Installation stages nothing, commits nothing and restarts no service.

🚂 The current platform

MB856 has been committed and pushed as 98c2296, version 3.6dev-20261020_070652. The development service was restarted and reported active/running. Production updates continue through the normal instance-by-instance workflow; this checkpoint does not claim that every production bot already runs the latest source.

Only the Icecast reader, conversion module and conversion argument handling changed in production code across these rounds. No database schema, private configuration or persistent-format change is required.

One radio report now describes one observation. An inch keeps its unit. A numerical overflow gets an honest error. Three small improvements, backed by the tests needed to keep the rest of the common room running. 🦉📻📏

You must be logged in to reply.