Suggested model tier: Opus 4.x medium for Task A (determinism recon — judgment-heavy); Sonnet 4.6 low effort for B/C
Context
The recorder. An oscilloscope captures a signal over time as a trace — Oscilloscope drives the simulation headlessly (no renderer, no UI clock) and captures the VoxelFrame stream into a VoxelTrace.
The load-bearing assumption of the whole epic is determinism — and right now that's an assumption, not a verified property. If CognitiveSceneRuntime reads wall-clock time or uses unseeded Random, captures won't reproduce, and Workbench tuning becomes unreliable. This ticket converts the assumption into a tested guarantee. Expect Task A to find at least one non-injected time or RNG source; that refactor is in scope here, not a surprise.
Objective
Oscilloscope.capture(...) produces byte-identical VoxelTrace output for identical inputs, with no renderer attached.
Expected outcomes
Oscilloscope in :phosphor-trace: capture(config: CaptureConfig): Result<VoxelTrace> where CaptureConfig(params, seed: Long, durationMs, fps, segments: List<TraceSegment>).
- Fixed-timestep drive: dt = 1/fps exactly; no wall-clock reads during capture.
- Any wall-clock/unseeded-RNG sources in the simulation path refactored to injected
TimeSource/seeded Random (default behavior unchanged for existing live consumers).
Technical constraints
JVM-first target is acceptable for v1 (capture runs on the Mac mini); the API stays in commonMain. No changes to live-rendering behavior — injection must default to current behavior. Result-typed errors.
Tasks
A — Determinism recon (comment before code): Audit the capture path (CognitiveSceneRuntime, VoxelFrameBuilder, choreographers, AtmosphereChoreographer, emitter/particle systems) for: wall-clock reads, Random without injected seed, iteration over unordered collections affecting output, float accumulation order. List every offender with file:line. STOP and wait — Miley ranks which to refactor vs. defer.
B — Injection refactor + Oscilloscope: Apply approved refactors (injected clock/dt + seeded Random). Implement Oscilloscope driving the runtime at fixed dt, collecting frames, assembling VoxelTrace via T1's codec.
C — Determinism proof: Test that runs capture twice with identical CaptureConfig and asserts the encoded bytes are identical. Second test: different seeds produce different traces (guards against a frozen RNG).
Validation / DoD
Byte-identical test green in CI (JVM); seed-divergence test green; existing live-path tests untouched and green (proves injection defaults preserved behavior); capture of a 5s clip completes headlessly with no Compose dependency on the classpath.
Out of scope
Cross-platform float determinism (capture happens on one machine — replay is data, so devices never re-run the math); playback (T3); UI (T4).
Human review gate
Miley reviews the Task A offender list and approves the refactor set before Task B begins.
Agent handoff prompt
You are implementing PHO-36 in socket-link/phosphor. Depends on PHO-35 (merged).
1. RECON FIRST: audit CognitiveSceneRuntime + VoxelFrameBuilder + choreographers
+ emitters for wall-clock reads, unseeded Random, unordered iteration.
Comment every offender with file:line. STOP for approval of the refactor set.
2. Refactor approved offenders to injected TimeSource + Random(seed); defaults
must preserve current live behavior exactly (existing tests stay green).
3. Implement Oscilloscope.capture(CaptureConfig): Result<VoxelTrace> — fixed dt,
headless, assembles via TraceCodec.
4. Tests: (a) two captures, same config → identical encoded bytes;
(b) different seeds → different bytes.
5. DoD: all green on JVM; no Compose imports anywhere in :phosphor-trace.
If recon contradicts any assumption in this ticket, STOP and comment.
Suggested model tier: Opus 4.x medium for Task A (determinism recon — judgment-heavy); Sonnet 4.6 low effort for B/C
Context
The recorder. An oscilloscope captures a signal over time as a trace —
Oscilloscopedrives the simulation headlessly (no renderer, no UI clock) and captures theVoxelFramestream into aVoxelTrace.The load-bearing assumption of the whole epic is determinism — and right now that's an assumption, not a verified property. If
CognitiveSceneRuntimereads wall-clock time or uses unseededRandom, captures won't reproduce, and Workbench tuning becomes unreliable. This ticket converts the assumption into a tested guarantee. Expect Task A to find at least one non-injected time or RNG source; that refactor is in scope here, not a surprise.Objective
Oscilloscope.capture(...)produces byte-identicalVoxelTraceoutput for identical inputs, with no renderer attached.Expected outcomes
Oscilloscopein:phosphor-trace:capture(config: CaptureConfig): Result<VoxelTrace>whereCaptureConfig(params, seed: Long, durationMs, fps, segments: List<TraceSegment>).TimeSource/seededRandom(default behavior unchanged for existing live consumers).Technical constraints
JVM-first target is acceptable for v1 (capture runs on the Mac mini); the API stays in commonMain. No changes to live-rendering behavior — injection must default to current behavior. Result-typed errors.
Tasks
A — Determinism recon (comment before code): Audit the capture path (
CognitiveSceneRuntime,VoxelFrameBuilder, choreographers,AtmosphereChoreographer, emitter/particle systems) for: wall-clock reads,Randomwithout injected seed, iteration over unordered collections affecting output, float accumulation order. List every offender with file:line. STOP and wait — Miley ranks which to refactor vs. defer.B — Injection refactor + Oscilloscope: Apply approved refactors (injected clock/dt + seeded Random). Implement
Oscilloscopedriving the runtime at fixed dt, collecting frames, assemblingVoxelTracevia T1's codec.C — Determinism proof: Test that runs
capturetwice with identicalCaptureConfigand asserts the encoded bytes are identical. Second test: different seeds produce different traces (guards against a frozen RNG).Validation / DoD
Byte-identical test green in CI (JVM); seed-divergence test green; existing live-path tests untouched and green (proves injection defaults preserved behavior); capture of a 5s clip completes headlessly with no Compose dependency on the classpath.
Out of scope
Cross-platform float determinism (capture happens on one machine — replay is data, so devices never re-run the math); playback (T3); UI (T4).
Human review gate
Miley reviews the Task A offender list and approves the refactor set before Task B begins.
Agent handoff prompt