# Handoff 2026‑02‑02 — R² vs Window Size Plot (Piecewise Fits)

## Context
This handoff documents a **locked‑in interpretation and plotting strategy** for the R² vs window‑duration diagnostics in the `envelope-decay-fit` sub‑project.

The underlying scoring logic is **piecewise by design** (`n = 2` by default). The current plot artifacts are not algorithmic errors but **visual misrepresentation caused by stitching multiple window sweeps into a single polyline**.

This document defines how the plot *must* be structured going forward so that it faithfully reflects the computation.

---

## Observed Issue (Root Cause)

- Multiple window sweeps / pieces are concatenated into a single `(x, y)` series.
- Window duration Δt therefore becomes **non‑monotonic** within the plotted series.
- Matplotlib draws straight lines between the end of one sweep and the beginning of the next.

Result:
- Large diagonal artifacts
- Misleading visual slope
- False impression of global continuity

Diagnostics already confirmed this:
- `dx_min < 0`
- `dx_non_positive_count > 0`

This behavior is **expected** given piecewise scoring and is not a bug in the fitting logic.

---

## Locked‑In Decision

### ✅ One R² curve per piece

Each piecewise function **must have its own R² trace** in the plot.

> A piecewise algorithm must produce a piecewise visualization.

There must **not** be a single polyline representing multiple pieces.

---

## Required Plot Structure

For `n` pieces (default `n = 2`):

- Plot **one R² vs Δt curve per piece**
- All curves share the same axes
- No concatenation of x/y data across pieces

### Legend

Use explicit labels:
- `LOG fit R² — piece 0`
- `LOG fit R² — piece 1`
- …

This makes it immediately clear:
- which piece stabilizes early
- which piece degrades late
- which piece drives breakpoint decisions

---

## Breakpoints

Breakpoint markers (vertical dashed lines) remain valid and unchanged:

- `Breakpoint 0`
- `Breakpoint 1`

They should intersect **all piecewise curves**, allowing visual inspection of:
- which piece dominates at the breakpoint
- whether the breakpoint lands in a stable R² region

---

## Explicitly Forbidden Pattern

🚫 Do **not**:
- concatenate multiple sweeps into one `(x, y)` polyline
- rely on NaN insertion *as a substitute* for proper piece separation

NaNs are acceptable only as a temporary debugging aid, **not** as the final design.

---

## Optional (Strongly Recommended) Enhancements

These are not required for correctness but align with the diagnostic philosophy of the project:

### 1. Plot‑level diagnostic annotation

If any series exhibits non‑monotonic Δt internally, annotate:

> ⚠ Non‑monotonic window sweep detected — piecewise traces separated

### 2. Visual emphasis

- Use consistent color per piece
- Optionally fade non‑selected pieces
- Optionally bold the piece selected for final ζ estimation

---

## Summary (One‑Line)

**Because the scoring is piecewise, the R² visualization must also be piecewise; each function segment gets its own R² curve, and a single global polyline is no longer allowed.**

---

## Status

- Interpretation: **locked**
- Plot strategy: **locked**
- Ready for implementation in OpenCode

