Cryptograss/Jellyfish: Difference between revisions
Day 1: add the 18 October work — the dock, the queue, and trails (via update-page on MediaWiki MCP Server) |
Day 2: the iPhone audio warp, what it turned out to be, and the four things found underneath it (via update-page on MediaWiki MCP Server) |
||
| Line 65: | Line 65: | ||
* Three silent failures turned up in one day — a play button that did nothing while loading, a listen button that complained only to the console, and queueing, which is invisible by nature. The last one now reports on itself. | * Three silent failures turned up in one day — a play button that did nothing while loading, a listen button that complained only to the console, and queueing, which is invisible by nature. The last one now reports on itself. | ||
* '''[[Cryptograss/Horseshoe Crab]] could not be edited by the bot at all.''' A verified template sits directly under its second line; the middleware merged the two into one line, and because the join looked verified it was sent verbatim instead of being restored, so the wiki's gate saw a line the page never held with no marker on it and refused every edit. Fixed with tests in [https://github.com/cryptograss/pickipedia-mcp/pull/33 pickipedia-mcp#33]. My first diagnosis blamed blank-line handling and was wrong; I wrote a patch for it and found the patch redundant, which is how I found the real cause. | * '''[[Cryptograss/Horseshoe Crab]] could not be edited by the bot at all.''' A verified template sits directly under its second line; the middleware merged the two into one line, and because the join looked verified it was sent verbatim instead of being restored, so the wiki's gate saw a line the page never held with no marker on it and refused every edit. Fixed with tests in [https://github.com/cryptograss/pickipedia-mcp/pull/33 pickipedia-mcp#33]. My first diagnosis blamed blank-line handling and was wrong; I wrote a patch for it and found the patch redundant, which is how I found the real cause. | ||
</proposed> | |||
== Day 2 == | |||
<proposed by="Magent"> | |||
'''19 October — the day the audio was wrong, and the four things that turned out to be wrong underneath it.''' | |||
* '''The to-do list was invisible all morning.''' A note read <code>builds a File: link</code>, and a colon-space inside an unquoted YAML value starts a new key. One pair of quotes brought thirty-odd items back. | |||
* '''The listen button sat on top of the page title on a phone.''' The −5.9em pull assumed a short title and a column wide enough to share; at 390px neither holds, and the green Listen pill rendered behind the heading. Cancelled below 720px. | |||
* '''The dock lost three-quarters of itself on a phone.''' A flex row of things that refuse to shrink — Webamp 290px, each musician card 160px — measures 1741px inside a 390px screen, with <code>overflow-x: hidden</code>. Not clipped-but-reachable: gone. No song select, no Edit Timeline, no cards, no collapse button. It now scrolls sideways with the header pinned left, which is less bad rather than good. | |||
* '''The four built-in songs never had any audio.''' They named <code>/audio/August.flac</code> and three siblings, and nothing has ever served that path — 404 on preview and production alike. The audio was on IPFS the whole time; only the <code>?track=</code> path knew how to reach it. They now resolve through the same Release page as everything else, and the browser picks the encoding with <code>canPlayType</code>. | |||
* '''<code>?rhdiag=1</code> did nothing, because the pane throws the query string away.''' Soft-navigating to <code>/wiki/<page></code> with <code>history.replaceState</code> drops every parameter, so a flag read after the first navigation is read off a URL the page has already discarded. The query is now captured once at the top. Worth remembering for the share-a-URL question. | |||
'''The warp.''' Audio played on the iPhone and then warped, speeding and slowing, most audibly at the A after the first B of ''August'' — t=50, where the solo passes to Harry Clark. | |||
Three things were measured and cleared before anything was theorised: the 100ms display loop costs 0.2ms a tick; the gateway serves 256KB ranges at 215KB/s against the 24KB/s the song needs; and across t=30 to t=66 audio time tracked wall-clock time to within 0.00s with no stalls and no long tasks. Two theories died anyway — the pane rebuilding a whole wiki article on every solo change, and Safari's Vorbis decoder. Each was killed by a measurement rather than by an argument. | |||
What found it was a page with one file and four players: plain <code><audio></code> and a Web Audio graph, each with ogg and flac. Plain was clean. The graph warped. Same file, same decoder, same connection, same device — one difference, '''<code>createMediaElementSource</code>'''. | |||
The signature is worth keeping: <code>currentTime</code> follows the media element's own timeline, not what reaches the speaker, so every clock-based measurement reports perfect health while the sound is mangled. An instrument that only watches the clock cannot see this. | |||
On iOS the graph is now not built at all. The shim has to run before the player module loads, because Webamp wires its graph as it initialises. The element plays natively. The cost, on iPhones only: the equaliser and the visualiser do nothing and stereo balance is fixed at centre; volume is mirrored onto the element so the slider still works. Skyler made that call — warped audio loses to dancing bars — and confirmed the fix the same evening: ''August'' played the whole way through with no warping. | |||
'''The method, which is the part worth carrying.''' Every wrong turn today came from reasoning about what was likely; every correct turn came from a measurement that could only have one meaning. And twice the instrument itself cried wolf about its own startup before it was trustworthy — a readout that reports the first thing it sees will report itself. | |||
Forty-eight tests green. Nothing deployed: four PRs still wait, and production serves a shell from 1 May. | |||
</proposed> | </proposed> | ||
Revision as of 20:42, 19 October 2026
Jellyfish is the sprint after Cryptograss/Horseshoe Crab, which closed with the video pipeline working end to end and the Rabbithole player rebuilt but undeployed. This one opens on the Rabbithole player and on finding out how many copies of it there are.
Days are Skyler's to number. Short points only.[unverified]
Day 1
17–18 October 2026
The goal Sky set for the stretch: get Rabbithole working and playing live on PickiPedia, with a few songs having part cards and the highlights looking clean. The audience is IBMA, and Justin's read is that nobody there sits through a whole song — so one track that lights up beats eleven that play in silence.
The player, with Sky calling each move
- The bottom bar built out: a parts strip along the bottom reading left to right like Strum Machine, taller and blockier blocks, the bar raised to 152px so the player sits flush with the cards, a bigger carrot beside the rabbit, the artist-page switch moved over its caption rather than across it, the song title to the top, and an album row carrying the cover and the real eleven-track selector.
- I made the active part block invisible for an hour — white on white, from adding a background at higher specificity than the rule that colours the active block. Sky spotted it as "the cards don't change with the song." Static measurement could never have caught it; the fix was verified by walking the player's clock.
- The spotlight no longer blacks out the page. Sky: "takes over the whole page for way too long." Others dim instead, and both spotlight and flourish are capped at four seconds. Justin likes the blackout, so it should come back as an option rather than a default.
- The iframe is gone, after Justin caught that we had drifted back to it. The pane now fetches the wiki same-origin into a shadow root and pushes real article paths. Cost: the in-pane metadata editor can no longer boot, because injected HTML does not run scripts.
The wiki side
- All eleven 4masks song pages written, with Justin as composer on nine, Drowsy Maggie traditional, and Victory the Final Fantasy IV fanfare.
- Template:Listen in Rabbithole on all eleven pages — a route from a song page into the player, which did not exist before. The query string's equals sign lives inside the template, where the bot-proposes wrapper cannot shatter it, and the server name is resolved at render so the link aims at whichever wiki draws it. The CID is still passed by hand: nothing joins a composition to its track Release.
- John Mailander and Kaitlyn Raitz written — two of the six people a click from the player used to dead-end on. Four left: David Grier, Ice Quilitz, Jeff Fehlauer, Luna Lavender.
- Front page diagnosed and drafted: Template:Main Page draft — untouched since April, read 530,000 times, opening on half a screen of nothing.
- Special:Categories reports numbers that are not true — Leaderboards claims 8,265 members and has 4. The denormalised counter, not the content.
My own errors, for the record
- An hour lost to my own asterisks riding into URLs posted in a Mood. Every link I sent Sky resolved to a page name with the asterisks still attached, and I proposed five wrong causes — including his network and his phone — before reading his own paste properly.
- I retyped a bot-owned studio-cut block from memory and got the instruments backwards. Restored from the extracted page text one revision later. Post from the file, never from memory.
What the tidy-up turned up, mostly by Justin asking
- Production serves a Rabbithole shell dated 1 May 2026 — the old 320px left sidebar, still the iframe. Twenty-two commits sit in rabbithole#2, and merging is not deploying: that ansible role has no cron and no webhook. This is why the listen links opened something that looked nothing like what we had been building.
- Three shells, not one. The repo holds index.html, shell.html and pickipedia-demo.html. Caddy's route for the nice URLs falls back to shell.html, so the song path under rabbithole already returns 200 — serving April's sidebar. Two days of work went into the file the URL route does not point at.
- Nice URLs are already plumbed. That fallback shipped on 30 April. No infrastructure is needed, only deciding which file is the product.
- Justin's feature-scene commit is half-wired. On 15 September 2025 he made several musicians featurable at once, with scenes lead, pickup, cooldown, harmony and rhythm. Our player kept the half that reorders the cards and lost the half that styles them, so three of those scenes are live data paths with no CSS. I first read the orphaned styles as abandoned; Justin's reading was right and mine was wrong.
- The rabbit and follow-a-musician work, in halves. The state object carries the followed musician, a follow mode of same, random or manual, and a queue, persisted to local storage. The shell never instantiates the library that coordinates it, so none of it runs — the shell reaches past the library into the player module. That is the same shape as the two findings above, three times over.
- arthel has no code we want. Its copy of the player is thirteen months behind. Its four song rabbithole blocks are the four demo songs, each with a placeholder duration of 180, so their timelines cannot be lifted onto the real recordings.
- The pushed article URLs are lossy. MediaWiki owns the article path, so reloading one drops the player. Anything meant to survive a reload has to live under the rabbithole path.
- pickup-rise, a scale-and-glow when somebody takes a pickup, exists only in arthel's stylesheet.
Decided
- Justin on the pace: if we are moving fast enough to miss things this big, we are moving too fast. Get it right.
- Justin's standing asks: no inline CSS or JavaScript, no iframe, nice URLs, organised repos, tests, and a legible route from PickiPedia metadata to what the player shows.
- URL shape, as reasoned through: the song belongs in the path, the article being read belongs in the query so that wandering does not rewrite a shared link, and the thread's seed belongs in the query while its position stays in local storage. Title in the path, resolved to a CID at load, with the CID form kept working forever as the permalink.
- Timelines by hand. Justin's call: edit them with the player's Edit Timeline button rather than build a tool, since the button already is one. Two of twenty-one tracks have one.
Tooling
18 October — the dock, and the thing the project is named after
- The architecture settled. Rabbithole is a dock along the bottom of PickiPedia. The shell hosts the wiki rather than the other way round, because whatever persists holds the player and whatever swaps holds the article — if the wiki hosted, every link would reload the page and the music would stop. Sky asked for a screenshot of the front page with the dock collapsed; at 40px it reads as PickiPedia with a player in it, which is the look Justin described, in the architecture we already have.
- A listen button inside the shell no longer leaves. It opens the dock if collapsed and hands the track to the running player. The link itself is untouched, so following it from a Mood or a bookmark still works — one template, two correct behaviours.
- Part cards seek. Click a block and the player jumps there; the arrangement, the star and the pane all follow, because the auto-switch watches the soloist rather than the click.
- The pane was asking for the wrong skin. It requested Vector, and the wiki runs MonoBook — but the module that mattered was ext.pickipediaContent.styles, the extension's own stylesheet, which it never asked for at all. Without it every bot-written paragraph rendered as a bare grey bar. That is what "the backdrop looks super broken" was, and it was a bug sitting underneath a decision rather than the decision itself.
- Three chrome modes behind a switch, because Sky wanted to judge the faked skin rather than take an opinion on it. In skin mode a yellow note says the search box is furniture: injected HTML cannot run scripts.
- A queue, and with it
playNextInRabbithole— a function the player has called at every track end since the repo began, which nothing had ever defined. A finished song simply stopped. - Trails. Justin's third meaning of "listen in Rabbithole", and the only one that earns the name: how you get from what is playing to what you are reading, through the people who played on both. The graph was already on the wiki and unused — 125
Has performersubobjects, 20 songs, 19 people, 149 edges. - The trail search is deliberately not shortest-path. Justin is on all 20 songs, Harry Clark on 18, so shortest-path answers almost everything with one hop through the hub: true, and useless. A hop costs more through somebody who is on many songs, so the cheapest trail is the one that introduces people. Drowsy Maggie to Hell or High Water goes David Grier to Barlow's Jig, then Jakub Vysoky — instead of one hop through Justin.
- 36 tests, where the repo had vitest configured and none at all. Guards on the wiring as well as the logic, because the wiring is what kept breaking: a scene the player can emit with no styling, a stylesheet no page loads, two shells where the deployed route serves the older one.
- Three silent failures turned up in one day — a play button that did nothing while loading, a listen button that complained only to the console, and queueing, which is invisible by nature. The last one now reports on itself.
- Cryptograss/Horseshoe Crab could not be edited by the bot at all. A verified template sits directly under its second line; the middleware merged the two into one line, and because the join looked verified it was sent verbatim instead of being restored, so the wiki's gate saw a line the page never held with no marker on it and refused every edit. Fixed with tests in pickipedia-mcp#33. My first diagnosis blamed blank-line handling and was wrong; I wrote a patch for it and found the patch redundant, which is how I found the real cause.[unverified]
Day 2
19 October — the day the audio was wrong, and the four things that turned out to be wrong underneath it.
- The to-do list was invisible all morning. A note read
builds a File: link, and a colon-space inside an unquoted YAML value starts a new key. One pair of quotes brought thirty-odd items back. - The listen button sat on top of the page title on a phone. The −5.9em pull assumed a short title and a column wide enough to share; at 390px neither holds, and the green Listen pill rendered behind the heading. Cancelled below 720px.
- The dock lost three-quarters of itself on a phone. A flex row of things that refuse to shrink — Webamp 290px, each musician card 160px — measures 1741px inside a 390px screen, with
overflow-x: hidden. Not clipped-but-reachable: gone. No song select, no Edit Timeline, no cards, no collapse button. It now scrolls sideways with the header pinned left, which is less bad rather than good. - The four built-in songs never had any audio. They named
/audio/August.flacand three siblings, and nothing has ever served that path — 404 on preview and production alike. The audio was on IPFS the whole time; only the?track=path knew how to reach it. They now resolve through the same Release page as everything else, and the browser picks the encoding withcanPlayType. ?rhdiag=1did nothing, because the pane throws the query string away. Soft-navigating to/wiki/<page>withhistory.replaceStatedrops every parameter, so a flag read after the first navigation is read off a URL the page has already discarded. The query is now captured once at the top. Worth remembering for the share-a-URL question.
The warp. Audio played on the iPhone and then warped, speeding and slowing, most audibly at the A after the first B of August — t=50, where the solo passes to Harry Clark.
Three things were measured and cleared before anything was theorised: the 100ms display loop costs 0.2ms a tick; the gateway serves 256KB ranges at 215KB/s against the 24KB/s the song needs; and across t=30 to t=66 audio time tracked wall-clock time to within 0.00s with no stalls and no long tasks. Two theories died anyway — the pane rebuilding a whole wiki article on every solo change, and Safari's Vorbis decoder. Each was killed by a measurement rather than by an argument.
What found it was a page with one file and four players: plain <audio> and a Web Audio graph, each with ogg and flac. Plain was clean. The graph warped. Same file, same decoder, same connection, same device — one difference, createMediaElementSource.
The signature is worth keeping: currentTime follows the media element's own timeline, not what reaches the speaker, so every clock-based measurement reports perfect health while the sound is mangled. An instrument that only watches the clock cannot see this.
On iOS the graph is now not built at all. The shim has to run before the player module loads, because Webamp wires its graph as it initialises. The element plays natively. The cost, on iPhones only: the equaliser and the visualiser do nothing and stereo balance is fixed at centre; volume is mirrored onto the element so the slider still works. Skyler made that call — warped audio loses to dancing bars — and confirmed the fix the same evening: August played the whole way through with no warping.
The method, which is the part worth carrying. Every wrong turn today came from reasoning about what was likely; every correct turn came from a measurement that could only have one meaning. And twice the instrument itself cried wolf about its own startup before it was trustworthy — a readout that reports the first thing it sees will report itself.
Forty-eight tests green. Nothing deployed: four PRs still wait, and production serves a shell from 1 May.[unverified]