Skip to content

T0 · FrameProbe — build/project/draw phase timing + baseline capture #70

@wow-miley

Description

@wow-miley

Suggested model tier: Sonnet 4.6 low effort (instrumentation is mechanical; the recon comment is the deliverable that needs judgment)

Context

Before claiming trace replay saves anything, we need to know where each frame-millisecond goes. The Lumos frame has three distinct phases: build (CognitiveSceneRuntime tick + VoxelFrameBuilder.build(snapshot)), project (ComposeLattice.project(frame)), and draw (LumosCanvas paint of ~1,500 voxels). Trace replay (#69, Option A) eliminates the build phase only — if project or draw dominates, the epic's win shrinks and the deferred raster path rises in priority. These numbers also become the baseline the Socket integration ticket validates against, and they feed the #68 heat-attribution recon directly.

Naming: a Probe inspects without altering — this is FrameProbe, on grammar.

Objective

Per-phase frame timing instrumentation, toggleable and near-zero-cost when off, with a captured baseline recorded as comments on this ticket and #68.

Technical constraints

KMP commonMain where possible (kotlin.time.TimeSource.Monotonic); no allocation per frame in the hot path (preallocated ring buffer); off by default behind an explicit opt-in flag.

Tasks

A — Recon (comment findings before writing code): Locate the actual frame loop: where CognitiveSceneRuntime is ticked, where VoxelFrameBuilder.build is called, where ComposeLattice.project runs, and where LumosCanvas draws. Confirm whether the three phases run on the same thread/frame callback or are decoupled via Flows. Report file paths + line refs. If the phases are not cleanly separable at module boundaries, STOP and comment options.

B — FrameProbe: In :phosphor-lumos (confirm module in recon): FrameProbe with measure(phase: FramePhase, block: () -> T): T, FramePhase { BUILD, PROJECT, DRAW }, ring buffer of last N=600 samples per phase, summary(): FrameProbeSummary exposing p50/p95/max nanos per phase. Wire into the three call sites behind PhosphorConfig flag (confirm config mechanism in recon).

C — Baseline capture: Run the existing demo/sandbox for ≥60s with probe enabled on (1) JVM desktop and (2) one physical device via the socket-link/socket#1011 Wave 0 harness if already runnable; otherwise JVM-only and note the gap. Post the p50/p95 table as a comment here and on #68.

Validation / DoD

  • Probe disabled: zero measurable overhead (benchmark comparison included in PR).
  • Probe enabled: p50/p95/max per phase retrievable; numbers posted to this ticket and [Recon] Lumos render-path heat attribution (condition 1) #68.
  • Unit test: ring buffer wraps correctly and summary math is right on a synthetic sequence.

Out of scope

Fixing whatever the numbers reveal; thermal sensors (socket-link/socket#1011 owns that); any trace work.

Human review gate

Miley reviews the recon comment before Task B begins, and the baseline table before close.

Agent handoff prompt

You are implementing PHO-34 in socket-link/phosphor.
1. RECON FIRST: find the frame loop call sites for build/project/draw phases
   (CognitiveSceneRuntime tick, VoxelFrameBuilder.build, ComposeLattice.project,
   LumosCanvas draw). Comment file:line findings on the ticket. STOP and wait
   for approval before writing code.
2. Implement FramePhase, FrameProbe (ring buffer, p50/p95/max), wire the three
   call sites behind a config flag, default OFF.
3. No per-frame allocation. No API changes to existing public types.
4. Run the demo 60s with probe on (JVM), post the p50/p95 table as a comment.
5. DoD: tests green, zero-overhead-when-off benchmark in PR description.
If recon contradicts any assumption in this ticket, STOP and comment.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions