# Screensaver and baked hold-narration rendering review

Reviewed 2026-10-03, America/Chicago. This is an evidence-based review, not a record of a deployed repair. No production renderer, narration MP3, or cue manifest was changed during this review.

## Original behavior to preserve

The original desktop field is a two-dimensional canvas simulation. The orb contains the resting field; holding the pointer unfolds it across the desktop. Pointer and orb form a binary gravity system. Icons drift, shrink, blur, disintegrate into particles, and orbit in an accretion band. When the temporary interaction ends, particles return and rebuild the icons.

The April 28 music extension made the orb a moving playback target. Dissolved icons should remain particles while music plays, and tapping the moving orb interrupts playback. The top active Star Map can become transparent, hide its controls, pass input through, and contribute stars to the same field. An early requirement for maximization was subsequently relaxed; it should not be reintroduced from an older description.

On May 10, David explicitly requested that **vacuuming all icons automatically initiate the full screensaver with music and baked narration**, and that it remain latched until dismissed. The manual star button uses the same path. This automatic behavior is part of the intended design, not merely an optional manual music visualizer. Browser autoplay refusal must remain an explicit pending-audio state rather than silently canceling the visuals.

The authored hold program is Cisco/Opus Number 1 with baked SOL-GPT commentary, rotating A → B → C → A. A is sparse/dry, B sharper, C increasingly self-aware. Live-generated commentary is a separate lane. The “Mute Screensaver Voice” control addresses that generated speech lane, not removal of narration already mixed into a hold MP3.

## Rendering change log

Dates below use local Chicago dates. Historical execution records establish the dated changes; file modification times alone do not establish a deployment date.

| Date / evidence | Change | Verification or limitation |
| --- | --- | --- |
| April 26 Git checkpoint `e1f6cb5` | Multiversal canvas, held-pointer binary field, icon disintegration/reassembly and immersion events already exist. | Recoverable historical source; compared directly with current renderer. |
| April 28 session | Local audio music mode; moving orb transport; Star Map point bridge, transparency, chrome removal, click-through input and accretion motion. | Session records contain successive corrections; several contemporary checks were syntax-only. |
| April 28 session | Block both idle-triggered and weak-gravity-triggered icon return while music plays. | Intended persistence is explicitly recorded. Current implementation has divergent hold conditions. |
| April 28, about 22:34–22:37 | Initial narrated hold loop becomes three complete 11:07 acts, with 3 / 6 / 9 authored cues. | Historical transcript and render commands preserved. |
| April 28, about 22:45–22:51 | Narration emphasis, fade-ins/outs, music ducking, limiter; padding and final trimming preserve the full track after a shortened-render problem. | Final FFmpeg command uses raw `assistant-default-hold-source.mp3`, sidechain compression, and a 667.08898-second trim. Current encoded masters probe at 667.115102 seconds. |
| May 10 | Add forced latch, manual star button, automatic icon-vacuum hold-playlist bootstrap, and retry after autoplay refusal. | User explicitly requested automatic music and baked narration after icon vacuum. |
| May 10 | Add editable track-relative cue timeline and full Settings transcript, plus separate generated-commentary placeholders. | Timeline exports JSON; editing it does not retime an existing MP3. |
| May 10 | Add two early lines per act, expanding 3/6/9 cues to 5/8/11. First remix truncated the track; the follow-up preserved 11:07. | Session reports rebuilt MP3s but explicitly lacks a full audible validation. |
| May 10 | User reports Track A's new “Please remain…” line before “Thank you…”. A temporary 1:35/2:35 retime was then reverted at the user's request to 1:08/2:18. | Code/manifest agreement was verified then; actual audible onset was not established. |
| May 17 | Builder gains explicit per-cue voice support. | Historical patch to `build_assistant_hold_tracks.py`; this does not alone prove a render happened that day. The explicit `early` default is evidenced by the June 18 inspection, not this patch. |
| May 27 file timestamps; known by June 18 | Expanded Early-voice public renders existed. | Preserved in `.pre-solgpt-restore-20260618-1738`; exact May 27 render execution was not recovered in this review. |
| June 18 | At David's request, restore original SOL-GPT recordings by copying `.hold-build` A/B/C masters over the public files; change cache version to `20260618-solgpt`; set future builder default to `sol-gpt`. | June session records the restoration. Today all three public-tree files still match `.hold-build` byte for byte. |
| April checkpoint → current renderer, whose mtime is June 21 | Multiple media inputs, per-media mute, external amplitude/bands, transparent canvases, calmer resting direction/motion, and pointer-default suppression added. | Verified source difference; not all individual edit dates recovered. Current sustained-field audio branch is restricted to touch/coarse-pointer devices. |
| October 3 review | Reproduced activation mismatch and stranded-icon state; recovered hold-render chronology and cue mismatch. | Controlled Chromium tests and local media inspection below. |

## Hold narration: original mix versus the retained cue manifest

These are **scheduled original render offsets** recovered from the final April FFmpeg command, not fresh speech-recognition alignments. The restored MP3s match the preserved April masters. The current JSON still carries the expanded May script and timings, despite identifying the audio as the restored SOL-GPT pass.

| Track | Original mix cues | Current manifest cues | Original opening | Manifest opening |
| --- | ---: | ---: | --- | --- |
| A | 3 | 5 | 1:25 — “Thank you for continuing to hold…” | 0:14 |
| B | 6 | 8 | 1:05 — “Thank you for holding. The system appreciates your patience…” | 0:12 |
| C | 9 | 11 | 0:35 — “Thank you for holding. This call is not being monitored…” | 0:10 |

Original A: **1:25, 4:45, 8:40**.

Original B: **1:05, 2:55, 4:35, 6:15, 7:50, 9:25**.

Original C: **0:35, 2:00, 3:15, 4:25, 5:35, 6:45, 7:55, 9:05, 10:10**.

The six May additions were “Please remain where you are in the song…”, “A brief reassurance…”, “This portion…managed waiting…”, “If the melody has become familiar…”, “You are now inside the efficient part of the loop…”, and “The music continues to suggest…”. Restoring the earlier complete recordings also rolled back that expanded audio content; leaving the expanded transcript in place did not restore those inserts.

The original machine-state lines are historical baked narration. They are not current CPU, RAM, disk, or service measurements.

## Confirmed defects and remaining limits

1. **Shell latch and canvas activation disagree.** `setAssistantMusicScreensaver()` honors forced activation without audio. The canvas requires active audio plus a coarse/touch pointer for its sustained audio drive. In an isolated browser harness using the live-served renderer, silent latch opacity stayed at 0 on both desktop and touch contexts. With injected active audio levels, desktop remained 0 while touch reached 0.96. Holding the pointer reached about 0.96; releasing it with a silent latch reduced opacity to about 0.000042. This reproduces a renderer state mismatch, not a full physical-iPhone playback test.

2. **Particle-budget eviction strands icons.** `spawnIconDisintegration()` removes particles above 520 without clearing the evicted icons' disintegrated state. `resetDesktopGravity()` skips those icons. In a stress fixture with 40 colocated icons, all 40 dissolved; after release and 700 frames, 16 still had `pointer-events:none` while field opacity was effectively zero. This is consistent with faded icons remaining over the teal desktop, although the screenshots alone do not establish the exact trigger sequence.

3. **Narration reference and rendered audio are different revisions.** The Settings view consumes the JSON manifest, but hold playback consumes the already mixed MP3. Their opening times and cue counts differ as above. The timeline editor cannot repair the audio merely by changing displayed timestamps.

4. **The current builder does not reproduce the preserved master recipe.** It takes `assistant-default-hold-loop.mp3` as its bed (the historically narrated single-loop asset), adds every manifest cue, applies speech EQ/loudness/gain and a limiter, and writes 96-kbit MP3. It does not contain the original sidechain ducking or clip fades. Running it could stack narration over an already narrated base. Do not treat a successful builder exit as restoration of the original mix.

No full 33-minute A/B/C listening cycle, fresh transcription alignment, or physical Safari test was completed in this review. Repairs should preserve the recovered original behavior and explicitly reconcile the later expanded script with the requested original voice.

## Evidence and preservation

- Pre-review runtime snapshot: `20261004T014952Z`, 5,161 items, `missing_sources: []`.
- Snapshot manifests preserve the renderer as a symlink, not its resolved bytes. Resolved source bytes were separately copied to `/mnt/sol-data/sol-stack/screensaver-audit/source-snapshot/`.
- The local `.git` is not recognized directly. A separate read-only object-access repository under the audit directory recovered checkpoint `e1f6cb5`; the live repository was not repaired or rewritten.
- Live local and Cloudflare-served visualizer SHA-256 both: `afb668f44a00e1a07e52cf2f2f8583141bd7c0f532363706f74cc824e847f6f9`.
- Hold A SHA-256: `77cae0573c32382ca975b1e87937d0ca3c8ed77fad1b2fbb957380e9b9746a22`.
- Hold B SHA-256: `e93bba8f95b5aa2769fea7ccf0e83686803bbc2d5c16118ffdb651361e2fe9f2`.
- Hold C SHA-256: `fe7a98eb50d3cfeeca5a6afa032bdd8a8efecd9782b1db2f87a22e1b38742ebc`.
- All three local MP3s: 44.1 kHz, mono, 667.115102 seconds; hashes match `.hold-build`.
- Cloudflare download of Track A matched the local hash. B and C downloads exceeded the 30-second per-file limit after partial transfer; their full public hashes were not verified. These incomplete transfers are not evidence of different content. Details: `/mnt/sol-data/sol-stack/screensaver-audit/public-audio-verification.json`.

Primary historical records:

- April session: `/home/david/.codex-chatgpt/sessions/2026/04/28/rollout-2026-04-28T11-28-19-019dd4eb-80f6-7a12-ac62-07ae4564c985.jsonl`, especially final mix command at line 2349.
- May session: `/home/david/.codex-chatgpt/sessions/2026/05/09/rollout-2026-05-09T11-32-58-019e0d95-c03e-7492-badb-c0f80a3503e9.jsonl`, especially the expansion/rebuild and user-reported ordering failure at lines 1263–1676.
- June restoration: `/home/david/.codex-chatgpt/sessions/2026/06/18/rollout-2026-06-18T17-19-07-019edcd1-07e8-7ac2-8640-e20e4342b831.jsonl`, lines 174–435.
- Extracted records and unexecuted historical FFmpeg recipe: `/mnt/sol-data/sol-stack/screensaver-audit/hold-history-excerpts.txt` and `historical-april28-final-mix.txt`.

Current sources: `www/assets/hue-visualizer.js`, `www/index.html`, `www/data/assistant-hold-loop-timings.json`, `www/ORB_HOLD_NARRATION_SCRIPT.md`, `www/ORB_BROADCAST_VISUALIZER_SUMMARY.md`, `www/programs/hold-narration-timeline.html`, and `bin/build_assistant_hold_tracks.py`.

## Follow-up repair checkpoint

PR #45, https://github.com/davidlones/davidlones.github.io/pull/45, prepares the latch, icon-budget recovery, autoplay-retry and cue-reference repairs. Tests passed locally and in GitHub; Chromium confirmed blocked-audio activation and dismissal. The original audio hashes remain unchanged. This is source-level completion, not live deployment: PR #45 remains open and root storage exhaustion blocked live writes at this checkpoint. The updated tracked chronology is `docs/screensaver-hold-rendering-review.md` in the public-source checkout. Recheck PR/deployment state rather than treating this dated note as permanent status.
