theallelectricsmartgrid

Audio UI Isolation Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development to implement this plan task by task. Steps use checkbox syntax for tracking.

Goal: Prepare a temporary signed iPad build that restores normal audio processing while independently disabling recurring UI rendering, so the two observed audio failure modes can be tested over Wi-Fi.

Architecture: Add two immutable launch-time flags to MainComponent. Preserve the installed tone behavior as the default, allow normal Nonagon processing with an environment value, and independently suppress visual refresh by hiding child components and skipping display/label/repaint work while retaining the message timer, state interchange, logging, and platform diagnostics. The parent handles wireless device control, recording, and deployment after code review.

Tech Stack: Existing JUCE 8.0.2 C++ source, Xcode signed iOS Release build, environment variables passed on app launch.

Global Constraints

Task 1: Implement and build independently selectable audio and UI test modes

Files: Modify JUCE/SmartGridOne/Source/MainComponent.h and MainComponent.cpp. Requirements include every Global Constraint above.

Interfaces: Consumes the existing m_nonagon.Process(bufferToFill, MakeIOInfo()), tone loop, MainComponent timer, and platform diagnostics. Produces the two launch flags and a signed app at /private/tmp/smartgrid-ui-isolation-ios-build/Build/Products/Release-iphoneos (report actual product path). Parent will launch with environment variables after review.

const bool m_useTestTone = juce::SystemStats::getEnvironmentVariable("SMARTGRID_AUDIO_TEST_MODE", "tone") != "normal";
const bool m_renderTestUi = juce::SystemStats::getEnvironmentVariable("SMARTGRID_UI_RENDER", "1") != "0";

Log Audio experiment audio_mode=%s ui_render=%d after configuring the log directory and before OpenAudioDevice. In prepareToPlay, retain the tone marker only for tone and log Audio test mode=normal; normal callback processing enabled for normal. Keep phase reset and existing preparation.

if (m_useTestTone)
{
    // Existing complete phase-continuous tone loop remains here.
    //
}
else
{
    m_nonagon.Process(bufferToFill, MakeIOInfo());
}

The comment above describes moving the EXISTING loop verbatim; do not replace its implementation with a placeholder. Preserve the invalid-rate clearing and all callback timing logs after the branch.

for (int i = 0; i < getNumChildComponents(); ++i)
{
    getChildComponent(i)->setVisible(false);
}

Leave the top-level app window alive. In paint, after filling the background, when UI is disabled draw the static text SmartGridOne: UI rendering paused for audio test and return. One initial repaint is allowed. Preserve normal paint behavior when enabled. Hidden controls must not trigger configuration actions.

xcodebuild -project JUCE/SmartGridOne/Builds/iOS/SmartGridOne.xcodeproj -scheme 'SmartGridOne - App' -configuration Release -destination 'generic/platform=iOS' -derivedDataPath /private/tmp/smartgrid-ui-isolation-ios-build -allowProvisioningUpdates build

Capture the full build output in /private/tmp/smartgrid-ui-isolation-ios-build.log, verify BUILD SUCCEEDED and report actual product path. Use sandbox escalation for signing/build/worktree writes when required. Do not remove old artifacts or rebuild other configurations.

Task 2: Optional automatic transport start for unattended UI comparison

The user identified the initially stopped transport and explicitly allowed starting in the running state. This small diagnostic extension lets the parent start identical normal UI-on and UI-off runs remotely. The original Task 1 behavior remains the default.

Files: Modify only JUCE/SmartGridOne/Source/MainComponent.h and MainComponent.cpp, this task’s scratch report, and checkboxes for Task 2. All other Global Constraints continue to apply. Baseline files are /private/tmp/smartgrid-autoplay-before-20260910/MainComponent.h and MainComponent.cpp. No commits or deployment. Existing Task 1 is already implemented and reviewed; do not redo it.

const bool m_startTestPlayback = juce::SystemStats::getEnvironmentVariable("SMARTGRID_AUDIO_TEST_PLAY", "0") == "1";
if (!m_useTestTone && m_startTestPlayback)
{
    m_nonagon.m_internal.m_running = true;
}

This write occurs before the audio device starts. No new audio-thread branch or recurring transport writes. Leave faders, patch loading, MIDI, clocks, input/output configuration and DSP unchanged. Do not persist the launch flag or transport state. The existing internal-clock saved config remains parent-owned.

Parent integration checklist