Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .agent/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ Analysis response shape:
samples-per-cycle + reliability flag + profile array).
- `/api/usaf/analyze` → native JSON: channel × line measurements grid +
per-channel detection limit + base64 channel thumbnails (no PNG
plots — frontend draws native charts).
plots — frontend draws native charts). Each line may include optional
`manual_points_by_channel` overrides keyed by channel name; the server
applies a manual 3-bar/2-gap profile calibration only to the matching
requested channel.
- `/api/fpn/compute` → small summary stats for live-drag ROI updates
(extended in `fpn-rewrite-v1` with `mean_signal`, row/col-only DSNU,
row/col peak frequencies, hot/cold counts, drift order).
Expand Down
6 changes: 6 additions & 0 deletions .agent/CHANGELOG_AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ with `?? null`).

---

## 2026-04-29 — usaf-channel-manual-points-v1 closed (Codex, GPT-5)

USAF manual profile extrema are now channel-scoped end to end: the picker stores `manualPointsByChannel`, Profile Preview re-measures the active display channel with its own saved 3-bar/2-gap points, saved configs preserve the map, and `/api/usaf/analyze` accepts `manual_points_by_channel` and applies overrides only to the matching analysis channel. Added a FastAPI regression for distinct HG-G/LG-G manual indices, documented the API contract, restarted the local webview server at `http://127.0.0.1:8765/`, and kept the original-code backup at `/Users/mini-09/BioSensorsLab/MantisAnalysis_backup_usaf_manual_points_20260429_000626`. Files: `mantisanalysis/server.py`, `web/src/usaf.tsx`, `tests/unit/test_usaf_manual_points_api.py`, `.agent/ARCHITECTURE.md`, `.agent/runs/usaf-channel-manual-points-v1/`. Smoke: Tier 0–3 PASS; pytest 306 passed / 4 skipped; Vite build PASS. Status: closed, pending optional manual browser walkthrough.

---

**2026-04-28 (Night) — play-export-and-roi-fixes-v1 INITIATIVE CLOSED — 7 Play-mode bugs fixed, multi-source job-based export, ROI vertex edit**

User reported seven defects in Play mode: (1) ROI vertices were
Expand Down
30 changes: 30 additions & 0 deletions .agent/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -773,3 +773,33 @@ the pre-merge Tier-4 gate will not run it.
keyboard-only control on a projector) surface concrete a11y issues,
re-introduce a targeted axe smoke for the affected surface — not a
blanket gate.


## D-0019 — USAF manual extrema are channel-local profile indices (2026-04-29)

**Status**: Active.

**Context**: A user found that manually corrected USAF Profile Preview
extrema could become wrong when switching Display channel and then
running multi-channel analysis. The old picker state treated manual
5-point extrema as line-level data, but the indices refer to sample
positions in a 1-D profile extracted from one concrete channel image.

**Decision**: Store manual extrema as `line.manualPointsByChannel[ch]`
in the React picker and send them to `/api/usaf/analyze` as
`manual_points_by_channel`. The FastAPI route looks up overrides by
the requested analysis channel and passes them to `measure_line` only
for that channel. Legacy unscoped manual bars/gaps remain a
display-preview fallback only; they are not fanned out across a
multi-channel analysis request.

**Consequences**:
- Users can calibrate `LG-R`, `LG-G`, `LG-B`, `LG-NIR`, and `LG-Y`
separately and run them together without cross-channel point reuse.
- Saved USAF configs now preserve `manualPointsByChannel`.
- Cross-channel physical registration remains out of scope; this
decision only scopes profile sample indices correctly.

**Revisit**: If the lab later wants one calibrated channel to seed
another channel, add an explicit "copy extrema to selected channels"
command rather than implicit reuse.
89 changes: 56 additions & 33 deletions .agent/HANDOFF.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,70 @@
# HANDOFF — current live state pointer

Last updated: **2026-05-07** — the `play-lod-ratio-tools-v1`
initiative addressing 6 user-requested Play-mode data-inspection
features (live cursor pixel readback; TBR ergonomics rework;
LoD/Ratio dual-mode rename with k·σ LoD calculation; flexible
labels + numericValue + unit; reorder; detachable FloatingWindow
panel). Seven milestones (M0 scaffold → M1 pixel-readback → M2
mode rename + migration → M3 table ergonomics → M4 FloatingWindow
pop-out → M5 LoD analysis modal → M6 reviewer pass + close).
3 reviewers spawned at M6 (fastapi-backend-reviewer,
frontend-react-engineer, risk-skeptic). risk-skeptic flagged 2 P0s
(degenerate-baseline collapses threshold to μ; cross-channel
baseline+signal silently produces meaningless number) — both
fixed inline before close, with diagnostic banners surfaced in
the LoD modal + a panel-level commit guard. All P1s resolved.
Initiative artifacts at
Last updated: **2026-05-15** — `usaf-channel-manual-points-v1`
merged (PR #3). USAF manual 5-point extrema are now channel-scoped
end to end: the picker stores `manualPointsByChannel`, Profile
Preview re-measures the active display channel with that channel's
saved 3-bar/2-gap points, and `/api/usaf/analyze` applies
`manual_points_by_channel[ch]` only to the matching analysis
channel. Initiative artifacts at
[`.agent/runs/usaf-channel-manual-points-v1/`](runs/usaf-channel-manual-points-v1/).
Landed on top of the prior `play-lod-ratio-tools-v1` closure
(2026-05-07): 6 Play-mode data-inspection features (live cursor
pixel readback; TBR ergonomics rework; LoD/Ratio dual-mode rename
with k·σ LoD calculation; flexible labels + numericValue + unit;
reorder; detachable FloatingWindow panel), 3 reviewers green at M6,
2 P0s caught and fixed inline. Artifacts at
[`.agent/runs/play-lod-ratio-tools-v1/`](runs/play-lod-ratio-tools-v1/).
Prior `play-export-and-roi-fixes-v1` initiative artifacts at
[`.agent/runs/play-export-and-roi-fixes-v1/`](runs/play-export-and-roi-fixes-v1/).
Prior PM-session ultra-review work (27-item Phase-A/B/C sweep,
plan at `/Users/zz4/.claude/plans/tranquil-growing-lollipop.md`)
was committed in `8a1e056` / `b01d8f7` / `d1c0a9b` before this
was committed in `8a1e056` / `b01d8f7` / `d1c0a9b` before that
session began.

## Current state of the working tree

- Branch: `main` (50 commits ahead of `origin/main`, still never
pushed — B-0010 still open). Most-recent commit is the B-0037
Phase 2-4 module extractions (sourceModes, RoiOverlay,
WarningCenter, SmallModals).
- **Uncommitted: play-export-and-roi-fixes-v1 closed but unpushed.**
All 7 user-reported Play-mode bugs fixed; 3 reviewers green; all
P0/P1 resolved + verified. Touches:
* `mantisanalysis/server.py` (overlay labels, export_video CRF +
ISP, MultiSourceVideoRequest with Field/Literal validation, 4
new `/api/play/exports/*` routes, JOBS shutdown hook).
* `mantisanalysis/export_jobs.py` (NEW — JobStore + ExportJob).
* `web/src/playback.tsx` (vertex drag/delete/insert, TBR overlay
channel picker + skip-gain, multi-source export polling +
progress UI, Spinbox decoupled validation, hi-res defaults).
* `tests/unit/test_export_jobs.py` (NEW — 11 tests).
* `.agent/runs/play-export-and-roi-fixes-v1/` (NEW — initiative
+ reviews/).
- Branch: `codex/usaf-channel-manual-points`.
- Uncommitted bugfix files:
* `mantisanalysis/server.py` — `ManualUSAFPointsIn`,
`LineSpecIn.manual_points_by_channel`, and per-channel override
lookup in `/api/usaf/analyze`.
* `web/src/usaf.tsx` — `manualPointsByChannel` state/config,
per-display-channel preview remeasurement, and analysis payload
emission only for matching analysis channels.
* `tests/unit/test_usaf_manual_points_api.py` — regression proving
HG-G and LG-G can use different manual profile indices in the same
analysis request.
* `.agent/ARCHITECTURE.md` and
`.agent/runs/usaf-channel-manual-points-v1/` — contract/status
documentation.
- Pre-existing untracked files still present and intentionally not
touched: `.agents/`, `START_MANTIS_WEBVIEW.md`.
- Backup of original code before this fix:
`/Users/mini-09/BioSensorsLab/MantisAnalysis_backup_usaf_manual_points_20260429_000626`.
- Local server is running on `http://127.0.0.1:8765/` from
`.venv/bin/python -m mantisanalysis --no-browser --port 8765`;
refresh the in-app browser to load the new backend/frontend.

## Smoke status, last verified 2026-04-29

- `.venv/bin/python scripts/smoke_test.py --tier 0` — PASS
- `.venv/bin/python scripts/smoke_test.py --tier 1` — PASS
- `.venv/bin/python scripts/smoke_test.py --tier 2` — PASS
- `.venv/bin/python scripts/smoke_test.py --tier 3` — PASS
- `.venv/bin/python -m pytest -q` — PASS, 306 passed / 4 skipped
- `PATH="/opt/homebrew/opt/node@24/bin:$PATH" npm run build` — PASS
- Live server `/api/health` and `/api/usaf/analyze` curl checks — PASS
- Browser screenshots/manual UI walkthrough deferred: Playwright is
not installed and Browser Use tooling was unavailable.

## Where to pick up next

1. Refresh `http://127.0.0.1:8765/` and manually try: calibrate
`LG-R`, switch to `LG-G`, calibrate separately, switch back and
confirm Profile Preview keeps each channel's saved extrema.
2. If manual UI behavior looks good, commit branch
`codex/usaf-channel-manual-points`.
- The **prior** "Three layered changes" listed below were **all
committed** before this session began — see commits `8a1e056`
(polish-sweep), `b01d8f7` (B-0037/B-0040/B-0041/B-0042), and
Expand Down
103 changes: 103 additions & 0 deletions .agent/runs/usaf-channel-manual-points-v1/ExecPlan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# ExecPlan — usaf-channel-manual-points-v1

Opened: 2026-04-29
Branch: `codex/usaf-channel-manual-points`
Owner: agent (per user bug report)

## 1. Goal

Make USAF manual 5-point calibration channel-specific so each analysis channel uses its own saved bar/gap positions.

## 2. Why (user value)

The current USAF picker stores manual extrema on a line without channel identity. The analysis modal then re-runs server auto-detection and ignores the user's manually corrected points, so per-channel resolution results can disagree with the picker preview.

## 3. Scope (in)

- `web/src/usaf.tsx`: store manual points as line × channel state, preserve them in config JSON, and send them to analysis.
- `mantisanalysis/server.py`: accept per-channel manual point overrides in `/api/usaf/analyze`.
- Targeted regression test covering channel-specific overrides.
- Minimal docs/status notes for the changed analysis contract.

## 4. Out of scope (deliberately deferred)

- Redesigning the analysis modal UI — this fix keeps the existing modal but feeds it correct measurements.
- Solving cross-channel physical registration — manual extrema remain per-channel sample indices, as requested.
- Changing channel key names or GSense extraction constants — forbidden project invariants.

## 5. Architecture impact

Touches the FastAPI adapter and React USAF mode only. Analysis math stays in `usaf_groups.py` and remains pure NumPy/SciPy.

## 6. UI/UX impact

Users can display `LG-R`, adjust extrema, switch to `LG-G`, adjust separately, and run multi-channel analysis; each channel uses its own saved points when available.

## 7. Backend / API impact

`LineSpecIn` gains optional `manual_points_by_channel` data for `/api/usaf/analyze`. Existing payloads without this field remain valid and continue to auto-detect.

## 8. Data model impact

USAF picker line objects gain `manualPointsByChannel`, keyed by channel name. Saved config JSON includes this map when present. No H5/session/channel schema changes.

## 9. Test strategy

- Unit/API: add targeted FastAPI TestClient regression for `/api/usaf/analyze`.
- Smoke: Tier 0, 1, 2, 3.
- Pytest: full suite.
- Browser: rebuild frontend and verify the server serves the built app; full Playwright is unavailable unless the optional browser dependency is installed.

## 10. Verification agents to invoke (at close)

- [ ] docs-handoff-curator
- [ ] risk-skeptic

Note: reviewer subagents are not spawned in this desktop thread unless explicitly requested by the user.

## 11. Milestones

- [x] **M1 — Backend contract** — `/api/usaf/analyze` accepts channel-keyed manual points.
- [x] **M2 — Frontend state flow** — USAF picker stores and sends channel-specific manual points.
- [x] **M3 — Regression coverage** — targeted test proves different channels can use different overrides.
- [x] **M4 — Verification and handoff** — smoke, pytest, build, docs/status updated.

## 12. Acceptance criteria

- [x] Manual extrema are saved per analysis channel.
- [x] Multi-channel analysis uses the override for the matching channel only.
- [x] Existing configs/payloads without manual points remain valid.
- [x] Tier 0–3 smoke green.
- [x] Full pytest green.
- [x] Frontend build succeeds.
- [x] Docs/status synced.

## 13. Risks

| ID | Risk | Severity | Mitigation |
|---|---|---|---|
| W-1 | Accidentally applying one channel's extrema to another channel | High | Payload keyed by channel name; backend lookup per channel. |
| W-2 | Breaking old saved USAF JSON configs | Medium | Keep legacy fields tolerated and optional. |
| W-3 | Analysis modal still confusing if auto-detected vs manual points are not visually labeled | Low | Preserve server echo of final bar/gap indices; document behavior in status. |

## 14. Rollback plan

Use the timestamped backup at `/Users/mini-09/BioSensorsLab/MantisAnalysis_backup_usaf_manual_points_20260429_000626`, or switch back to `main` / revert this branch's diff.

## 15. Decisions

- 2026-04-29 **decision**: Store manual extrema as profile sample indices keyed by channel name, not by display mode or gain family, because indices are channel-profile-local.

## 16. Surprises & discoveries

- 2026-04-29 The picker preview already supports server-side manual point measurement for one channel; the missing link is persistence and `/api/usaf/analyze` payload propagation.

## 17. Outcomes & retrospective

Closed 2026-04-29. The fix keeps user calibration tied to the channel whose profile was displayed: `manualPointsByChannel` in React state/config, `manual_points_by_channel` in the analysis API payload, and a per-channel lookup on the FastAPI side before calling `measure_line`. Profile Preview also labels whether the active display channel is using saved manual extrema or auto extrema.

Automated verification was green: Tier 0–3 smoke, full pytest, targeted API regression, Vite build, and a live-server curl against `/api/usaf/analyze` proving HG-G and LG-G received distinct manual indices. Browser screenshots were deferred because Playwright is not installed and Browser Use tooling was unavailable in this desktop thread.

## 18. Final verification checklist

Tracked in `Status.md`.
Loading
Loading