# PWHAMSS: Personal Workshop for Human-Device Animation and MIDI Sync Systems

Version 0.0.1-draft · Status: speculative draft · Updated 2026-11-08

> **Speculative draft.** No Pop Boll hardware has shipped, and nothing on this page has been built or validated on hardware. Names, fields and limits will change without notice, and nothing here is an offer, a commitment or a promise of compatibility. We would love to hear about partnership, OEM and dev-kit ideas: use the contact form on this site.

PWHAMSS is the family of Pop Boll devices that a person works on alongside the band, and the name of the web simulator at popboll.com/pwhamss where those devices are built before they exist. The first PWHAMSS device is the [Glass Snipler](glass-snipler.md). The [overview page](index.md) introduces the rest of the ecosystem.

## 1. What the family is

The Pop Boll plays by itself. Sixteen virtual musicians jam, seven judges score every take, and the ball writes and plays songs from licensed corpora with nobody touching it. A PWHAMSS device is the other half of that idea: a place where a person stands at the keys with the same band, pulling material out of the same corpora, cutting it, playing it and handing it back.

The expansion of the name says what the family is for:

| Part | Meaning |
| :--- | :--- |
| Personal Workshop | one person's working surface, with their own library of sniplets, riffs, loops, beats and macros that follows them from device to device |
| Human-Device Animation | the device animates: the key legends, the matrix of lights, the Workshop and the band's reactions all move with what the person does, and what the band does |
| MIDI Sync Systems | everything is MIDI first, on one clock, so the person, the band, the corpora and any dock or cartridge agree on the beat |

A PWHAMSS device runs **Bollawax**, the Boll's song factory, so the band and the judges are the same code on the same corpora. What the family adds is a person in the loop and the surfaces a person needs.

## 2. Shared principles

Every PWHAMSS device is expected to keep these, and the Glass Snipler is the first to be built to them.

- **An always-visible Workshop.** A touch surface that never goes away, holding the popboard (the lanes of material you are working on), one bar ruler, a loop window, the transport and the band's listening log. Modes change what the keys do; the Workshop stays.
- **Context-switching key underlays.** The keys are transparent and sit over a display, so every key shows what it does right now: its legend, tint, state and stamp. A K-mode key is a letter, a P-mode key is a pad or a scale degree, an S-mode key is a card from your library, and the same key changes between them with no printed legend to contradict it.
- **One frame for every renderer.** The device is a pure state machine that turns events into frames. The web simulator, the slab's LCDs and its LED matrix all draw the same frame. Nothing a renderer shows may be invented locally, and a frame is a pure function of the event history.
- **HAMS sync of the person's library.** The person's sniplets, keymaps and settings belong to the person, not the device, and follow them through **HAMS**, the Bollawax sync system that already carries a person's songs, ratings and guilds between Bolls and the website. Local first: every device keeps a full copy and works offline for weeks.
- **Corpora and licensing unchanged.** PWHAMSS devices read the same licensed corpora from bollawax.org as the Boll, under the same terms. Derived stems and stem MIDI are corpus assets minted once, server side, and downloaded like any other. No PWHAMSS device creates corpora, and nothing here changes what a corpus licence allows.

## 3. The web simulator at popboll.com/pwhamss

During development the simulator is visible to **superusers only**. Everyone else, signed in or not, sees the site's ordinary not-found page for `/pwhamss` and for its API, never a permission error. When the design settles the gate will open in stages.

**What it shows.** A pixel-faithful drawing of the Glass Snipler in layout A, scaled to the browser window at a fixed aspect ratio: the full-width Workshop on top, the knob row with the pad and the mode diamonds, the 48 keys over their underlay and the six side keys. An optional LCD toggle shows the frame's matrix and status large, standing in for the external LCD. The library is seeded on first use from the built-in corpus, so the simulator starts with real stems and real derived riffs, loops and beats, each carrying its song's stamp.

**How a real keyboard maps onto the device.** The four physical QWERTY rows of your keyboard are the four rows of the device: the digit row is row 0, the Q row is row 1, the A row is row 2, the Z row is row 3. In K mode that makes typing on your keyboard typing on the device. In P, S and A modes the same physical keys press the pads, degrees, cards and stems that currently occupy those positions. Other inputs:

| You do | The simulator sends |
| :--- | :--- |
| press and release a key | key down and key up, with a pressure value |
| scroll the mouse wheel over a knob | knob events, one detent per click |
| click and drag on the pad | pad down, move and up in 0 to 1 coordinates |
| click a lane, the loop window or the transport | Workshop touch events |
| click a diamond | a mode event |
| type with the simulator focused in K mode | text events |

While the transport is playing the browser sends ticks at 10 Hz (estimate) so the playhead advances; the simulator never reads a clock of its own.

**It runs the same state machine the device will.** The simulator's canvas is a renderer and nothing more. Events go to the server, where one Snipler instance per signed-in superuser handles them and returns the frame; the browser draws it. The instance and its library are persisted, so a reload resumes the session. When hardware exists, the slab's screens will draw the same frames from the same code.

## 4. Sniplets, in brief

A **sniplet** is a piece of MIDI with a length in bars, a native tempo and a lock, a key, a Groove, a Guild (Family), an Instrument, an **AGI** flag ("looping is A Good Idea"), a privacy flag and a finished flag. The kinds are `sniplet` (song-length), `riff`, `loop`, `beat` and `macro`. Ids are content fingerprints, so the same notes filed twice are one sniplet. **SNIP POP** lifts material out; **SNIP PUT** drops it on the popboard. The [Glass Snipler page](glass-snipler.md#5-sniplets) has the full field list and the fitting rules.

## 5. The frame and event contract

This is the developer-facing summary. The full shapes live with the code and will be published as a schema when they stop moving.

**Events** go from a renderer to the Snipler. Each is a JSON object with a `type` and a `t_ms`, integer milliseconds on the renderer's monotonic clock. Renderers may batch events; the reply is the frame after the last one.

```json
{"events": [
  {"type": "mode", "mode": "S", "t_ms": 120400},
  {"type": "key_down", "key": 14, "pressure": 0.62, "t_ms": 120655},
  {"type": "key_up", "key": 14, "t_ms": 120790},
  {"type": "side_down", "side": 4, "t_ms": 121002},
  {"type": "side_up", "side": 4, "t_ms": 121090},
  {"type": "tick", "t_ms": 121100}
]}
```

| Type | Fields |
| :--- | :--- |
| `key_down`, `key_up`, `key_pressure` | `key` 0 to 47; `pressure` 0 to 1 on down and pressure events |
| `side_down`, `side_up` | `side` 0 to 5 |
| `mode` | `mode`: `K`, `P`, `S` or `A` |
| `knob` | `knob`: `S`, `M`, `L` or `H`; `delta` in detents |
| `pad_down`, `pad_move`, `pad_up` | `x`, `y` in 0 to 1, origin top-left |
| `touch` | `target` (lane, loop start, loop end, transport, guts, header), `index`, `action` (tap, long, drag), `value` |
| `tick` | none; advances the transport to `t_ms` |
| `text` | `text`: typed characters from a real keyboard |

Unknown event types are ignored and never fatal. Keyboard shortcuts are the renderer's business: it turns them into these events.

**Frames** go from the Snipler to a renderer. A frame is the whole display state, abridged here to one key card, one side card, one knob and one lane:

```json
{
  "v": 1, "t_ms": 121100, "mode": "S", "layer": "0", "layer_held": false,
  "status": "S · page 1/3 · 1 selected · 4 bars on board",
  "keys": [{"glyph": "", "sub": "", "label": "Velvet Hook", "tint": "#9BE26B",
            "field": 0.0, "band": 0.0, "state": "selected",
            "stamp": ["bolt", "cup", "moon", "fish"], "marks": ["agi"]}],
  "side": [{"glyph": "ENT", "sub": "", "label": "open guts", "tint": "#9BE26B",
            "field": 0.0, "band": 0.0, "state": "pressed", "stamp": null, "marks": []}],
  "knobs": [{"id": "L", "label": "page", "value": 0.0, "display": "1/3"}],
  "workshop": {
    "view": "board", "bpm": 120.0, "key": "F#m", "easy": true,
    "transport": {"playing": false, "recording": false, "playhead_beat": 0.0,
                  "loop": [0, 4], "bars": 4, "cue": false},
    "lanes": [{"id": "sn_3f9a1c77be02", "name": "Velvet Hook", "kind": "riff", "bars": 2,
               "native_bpm": 143.0, "locked": true, "gain": 0.8, "mute": false, "solo": false,
               "cue": false, "stamp": ["bolt", "cup", "moon", "fish"], "tint": "#F3E97A",
               "fit": "loop", "repeats": 2, "enter_bar": 0, "preview": [[0, 0.5, 66, 96]]}],
    "guts": null, "text": null, "picker": null,
    "band": {"listening": ["Vespera"], "log": []}
  },
  "matrix": {"w": 26, "h": 16, "rgb": "000000000000…"},
  "selection": ["sn_3f9a1c77be02"], "held": [], "toast": null
}
```

The rules a renderer can rely on:

- `keys` always has 48 cards and `side` always has 6, in device order; `knobs` has 4, in the order S, M, L, H.
- A card is drawn from its own fields alone: `glyph`, `sub`, `label`, `tint`, `field` and `band` (0 to 1 meters), `state` (idle, selected, held, pressed, dim, empty, armed or active), an optional 4-glyph `stamp` and a list of `marks` (agi, lock, draft, ear, now).
- `matrix.rgb` is 416 pixels × 6 hex characters, row-major from the top-left.
- `workshop.view` is one of board, guts, keymap, text or picker; the matching sub-object is present and the others are `null`.
- The frame validates against a published check; every frame the Snipler produces in its tests must pass it.
- The envelope version `v` is 1. Additions within a major version are new optional fields; removing or changing the meaning of a field is a new major version.

## 6. Routines and Bolltridges

PWHAMSS devices sit inside the existing ecosystem rather than beside it.

- **The compute in a PWHAMSS device is a Bolltridge.** The Glass Snipler's Raspberry Pi runs one signed image, `bollawax-snipler`, and speaks to the Boll core over the same contract as a cartridge docked under a Boll: [bollardeck Part C](bollardeck.md#17-part-c-bolltridges) for clock, MIDI, voice takeover, stem offers and image updates. Inside the slab the link is internal, but the image model, the signing and the `latest.json` update path are those of the [Bolltridge device class](bollard.md#17-bolltridge-device-class).
- **Routines still run on the Boll core.** Routines are Python hooks into the song factory, described in [bollardeck Part B](bollardeck.md#11-part-b-routines), and they run only on a person's own device. A PWHAMSS device changes nothing about that: a routine sees the same song factory, and the person's sniplets reach the band only by the band stealing them from the cue stream, which is a riff-book trade, not a routine hook.
- **Docks and accessories** see a PWHAMSS device as a Boll that happens to have a person at it. The now-playing, stems, beat and light messages of [bollardeck Part A](bollardeck.md#2-part-a-docks) are unchanged.
- **Stand-alone Snipler cartridges** for an ordinary Boll are possible in principle because of the contract above, and not planned for v0.0.1.

## 7. Roadmap

| Version | Milestone | What exists at the end of it |
| :--- | :--- | :--- |
| v0.0.1 | sim | the web simulator at popboll.com/pwhamss for superusers, driving the real engine on sniplets derived from the built-in corpus; the state machine, the library, the keymap and the board; these two spec pages |
| v0.1 | sound | the soundfont player and the three house synths in the browser as AudioWorklets with numpy twins, pinned by shared test vectors; sniplets audible on the popboard |
| v0.2 | stems | audio stems and stem MIDI minted server side into the morpus for official corpora; A mode plays and pops real stems; separation of local material on the device |
| v0.3 | band trades | the band steals finished public sniplets from the cue stream and may gift back; trades shown on the device page; HAMS sync of the person's library |
| next | hardware prototype | a Glass Snipler slab in layout A on a Raspberry Pi 5 Bolltridge and an Uno Q core, drawing the same frames as the simulator |

Dates are not given. Nothing here has a shipping date, and there is no hardware yet.

## 8. Status and open items

- **Built so far:** nothing on hardware. The simulator and the state machine are in development.
- **Estimates:** every timing on this page, including the 10 Hz tick rate and the key gesture thresholds on the Glass Snipler page.
- **The frame schema** is published here in prose and example only. A machine-readable schema follows when the fields stop moving.
- **Other PWHAMSS devices** beyond the Glass Snipler are not specified. The principles in §2 are what a second device would have to keep.
- **HAMS sync of sniplets** and the Guild (Family) link to HAMS guilds are intended and not designed.

## 9. Licence

Proposed, and not yet final, as for the other pages on this site: the specification text under CC BY 4.0, and code under Apache-2.0. These cover the document, not the project's names and logos.
