# Phase 11: Frame Repository and Subset Grid Compilation - Context

**Gathered:** 2026-04-13
**Status:** Ready for planning

<domain>
## Phase Boundary

Decouple capture from grid compilation. Long-running capture sessions persist frames to disk in a frame repository. Agents can then query, filter, and select subsets of stored frames using flexible time/index-based selectors, and compile those subsets into grid images on demand. New MCP tools for repository capture, frame querying, and subset grid compilation. Repository is session-scoped with automatic retention-based cleanup.

</domain>

<decisions>
## Implementation Decisions

### Frame Subset Query Modes
- **D-01:** Agents select frame subsets using five query modes, all relative to capture start:
  1. **Start time + end time** — `from_ms` and `to_ms` (both relative to capture start, in milliseconds)
  2. **Start time + length** — `from_ms` and `length_ms` (duration window)
  3. **Start frame + end frame** — `from_index` and `to_index` (inclusive frame indices)
  4. **Start frame + count** — `from_index` and `frame_count` (starting index + number of frames)
  5. **All frames** — no query params, returns entire session
- **D-02:** All five modes support an optional `max_frames` ceiling. When the selected range contains more frames than `max_frames`, frames are evenly distributed across the range (uniform sampling). This lets agents say "give me 9 frames from the first 30 seconds" for a clean 3x3 grid regardless of capture density.
- **D-03:** Query mode is inferred from which parameters are present — no explicit `mode` field needed. Validation rejects ambiguous combinations (e.g., both `to_ms` and `length_ms`).

### Repository Storage
- **D-04:** Each frame saved as an individual JPEG file in a session directory: `.screen-timelapse/frames/{session-id}/{index}.jpg`. JPEG matches the existing capture pipeline output (frames are already JPEG-compressed per `jpegQuality` config). Metadata stored in a sidecar `manifest.json` per session.
- **D-05:** The `manifest.json` stores: session ID, capture config used, start timestamp (ISO), frame count, frame manifest (array of `{ index, elapsed_ms, filename, size_bytes }`), session state (capturing/complete/error), and any skipped frame records.
- **D-06:** Repository root path follows the profiles convention: configurable via `SCREEN_TIMELAPSE_FRAMES_PATH` env var, defaulting to `.screen-timelapse/frames/` relative to CWD.

### Retention & Cleanup
- **D-07:** Repository sessions have a 24-hour retention period. Sessions older than 24h are automatically purged on server start and periodically during operation (lazy cleanup on list/query operations). This prevents unbounded disk growth while keeping frames available for lengthy working sessions.
- **D-08:** Agents can explicitly delete a session before the 24h window via a delete tool. Explicit cleanup is encouraged for agents that know they're done with a session.
- **D-09:** The 24h retention applies from session creation time, not last access. This keeps the policy simple and predictable — agents know exactly when frames will disappear.

### Capture Lifecycle
- **D-10:** A new `start_repository_capture` tool starts a long-running capture that persists frames to disk instead of holding them in memory. It accepts all the same parameters as `start_capture` (including `screenshot_profile` and `timing_profile`), but frames are written to disk as they're captured rather than accumulated in RAM.
- **D-11:** Repository captures have a higher default `max_frames` ceiling (200 vs current 50) since disk storage removes the RAM constraint. The `max_frames` limit on the capture itself prevents runaway disk usage from a forgotten session.
- **D-12:** Repository captures run asynchronously — `start_repository_capture` returns immediately with the session ID. Agents poll status via `get_capture_status` (existing tool, extended to cover repository sessions).
- **D-13:** Repository sessions track state: `capturing` (in progress), `complete` (all frames captured), `error` (capture failed). Agents can query frames from a `capturing` session — they get whatever has been captured so far (live tail).

### Subset Grid Compilation
- **D-14:** A new `compile_subset_grid` tool takes a session ID + query parameters (D-01) and produces a grid image. Returns the grid as a base64-encoded JPEG (same format as existing grid resources).
- **D-15:** `compile_subset_grid` reuses the existing `compileGrid()` function from `grid-compiler.ts`. The tool loads selected frame files from disk into `CaptureFrame[]` format and passes them through the existing pipeline (including delta highlighting, idle compression, timestamp overlays if requested).
- **D-16:** Multiple subset grids can be compiled from the same session — the frames on disk are not consumed or modified. An agent can compile "first 10 seconds", then "last 10 seconds", then "every 5th frame across the whole session" from the same capture.
- **D-17:** `compile_subset_grid` accepts the same diagnostic options as `start_capture`: `delta_highlight`, `compress_idle`, `jpeg_quality`. These are per-compilation, not per-session — the same frames can be compiled with different diagnostic treatments.

### Frame Listing & Inspection
- **D-18:** A `list_repository_sessions` tool returns all active repository sessions with: session ID, capture config summary, frame count, start time, elapsed duration, state, and disk usage. Includes the retention deadline (when auto-purge will remove it).
- **D-19:** A `list_repository_frames` tool for a given session returns the frame manifest: index, elapsed_ms, and optionally a `changes_from_previous` metric (boolean or percentage) so agents can identify which frames are interesting before compiling a grid.
- **D-20:** `list_repository_frames` accepts the same query parameters as `compile_subset_grid` (D-01), so agents can preview what a query would return before actually compiling the grid. The `max_frames` + even distribution logic applies here too.

### Agent-Power Features
- **D-21:** `compile_subset_grid` supports a `label` parameter — a short string burned into the grid image as a title overlay. Lets agents annotate grids like "Before fix" / "After fix" for side-by-side comparison without external context.
- **D-22:** `list_repository_frames` returns a `change_summary` for the full session: total frames, frames with significant changes, longest idle stretch, most active period. Gives agents a quick read on session dynamics before querying subsets.
- **D-23:** `start_repository_capture` supports a `session_name` parameter (optional string) so agents can name captures meaningfully (e.g., "deploy-watch", "flicker-debug") instead of using opaque UUIDs. Named sessions can be referenced by name in all repository tools as an alternative to session ID.
- **D-24:** A `delete_repository_session` tool explicitly removes a session and its frames from disk. Returns freed disk space. Works by session ID or session name.
- **D-25:** `compile_subset_grid` returns metadata alongside the grid: frame count in compilation, time span covered, query parameters used, grid dimensions. Agents get full provenance for every grid they compile.

### Claude's Discretion
- Internal file naming conventions (zero-padded indices, etc.)
- Manifest JSON structure and field ordering
- Exact change detection algorithm for D-19 (can reuse existing pixel-compare module)
- Periodic cleanup interval (how often to check retention during operation)
- Whether `get_capture_status` returns partial frame count for in-progress repository captures
- Error message wording
- Sort order for session and frame listings

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

No external specs — requirements fully captured in decisions above.

### Codebase References
- `src/types.ts` — `CaptureConfig`, `CaptureFrame`, `CaptureSession`, `SessionState` — repository types extend these
- `src/capture/session-manager.ts` — `SessionManager` class, in-memory session pattern to parallel for disk-backed sessions
- `src/capture/scheduler.ts` — Capture scheduling logic, reusable for repository captures
- `src/processing/grid-compiler.ts` — `compileGrid()` function, reused directly for subset compilation
- `src/processing/pixel-compare.ts` — Change detection, reusable for frame change metrics (D-19)
- `src/processing/idle-compressor.ts` — Idle frame detection, reusable for change summary (D-22)
- `src/profiles/profile-manager.ts` — File persistence pattern (JSON read/write), env var config path pattern
- `src/profiles/profile-resolver.ts` — Profile resolution pattern, reusable for repository captures
- `src/server.ts` — Tool registration pattern, `start_capture` implementation as template for `start_repository_capture`

### Phase Cross-References
- `.planning/phases/08-screenshot-profiles/08-CONTEXT.md` — Profile storage pattern (D-01, D-06), `capture_from_current` pattern (D-13)
- `.planning/phases/09-timing-profiles/09-CONTEXT.md` — Timing profile merge semantics (D-10, D-11), built-in presets pattern

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- `compileGrid()` in `grid-compiler.ts`: Accepts `CaptureFrame[]` + options. Subset compilation feeds disk-loaded frames through this unchanged.
- `compareFrames()` in `pixel-compare.ts`: Pixel-level change detection between frames. Reusable for `changes_from_previous` metric.
- `compressIdleFrames()` in `idle-compressor.ts`: Idle stretch detection. Reusable for `change_summary` computation.
- `ProfileManager` in `profile-manager.ts`: File I/O pattern (read/write JSON, env var path, lazy init). Repository manifest follows the same pattern.
- `Scheduler` in `scheduler.ts`: Timer-based capture loop with drift correction. Repository capture reuses this with a disk-write callback instead of memory accumulation.

### Established Patterns
- **JPEG frame buffers**: Frames are already JPEG-compressed in the capture pipeline. Repository stores these as-is — no re-encoding needed.
- **Singleton managers**: `SessionManager`, `ProfileManager` are module-level singletons. `RepositoryManager` follows suit.
- **Zod schemas for tool input**: All tools use zod validation. New repository tools follow the same pattern.
- **Snake_case MCP params**: `from_ms`, `to_ms`, `from_index`, `frame_count`, `max_frames`, etc.

### Integration Points
- `start_capture` in `server.ts`: Template for `start_repository_capture` — same profile resolution, target factory, but disk-backed
- `get_capture_status` in `server.ts`: Extend to report repository session status
- `CaptureFrame` type: Repository frames loaded from disk must match this interface for `compileGrid()` compatibility

</code_context>

<specifics>
## Specific Ideas

- **User directive (from Phase 8):** Frame subset selection must support five query modes with even-distribution `max_frames` ceiling. This is the primary user requirement for Phase 11.
- **User directive:** Repository sessions are NOT long-lived. 24h retention prevents disk bloat while covering lengthy working sessions.
- **User directive for all v1.2 phases:** Full creative discretion granted — Claude should ideate, decide, and introduce features that maximize tool power and flexibility for agent consumers.

</specifics>

<deferred>
## Deferred Ideas

- **Cross-session frame comparison**: Compile grids mixing frames from different sessions (e.g., "before deploy" vs "after deploy" in one grid). Powerful but adds complexity — agents can compile two separate grids instead.
- **Frame annotation**: Agents label individual frames with text tags (e.g., "clicked button", "page loaded"). Useful for debugging but belongs in a separate capability phase.
- **Streaming grid updates**: Live-updating grid resource that auto-refreshes as new frames are captured. Cool but conflicts with MCP's request-response model.

None — discussion stayed within phase scope.

</deferred>

---

*Phase: 11-frame-repository-and-subset-grid-compilation*
*Context gathered: 2026-04-13*
