MC /reports listing perf — cache or manifest (slow rclone scan) [non-breaking]
## Goal Fix the slow MC `/reports` LISTING page. After MC-4867 (reports now cloud-first on the rclone GDrive mount), the listing takes ~21s cold AND warm because it scans + read...
StateDoneNext ActionClosedOwnerLuciRuntimeClosedAge4d ago
Ticket is done; runtime is closed.·profile claude_opus_1m_medium
Description
MC-4873
## Goal
Fix the slow MC `/reports` LISTING page. After MC-4867 (reports now cloud-first on the rclone GDrive mount), the listing takes ~21s cold AND warm because it scans + reads metadata (title/date) from ~340 report files over the cloud mount on EVERY request. Individual report serving is fast — only the index is slow. Make `/reports` render in <2s warm with NO dropped reports.
## Context
Live MC = `~/workspace/mission-control/app.py` @ master (deployed f307977). Listing is built in app.py's report-listing functions (glob the report bases for *.html/*.md, read each file head for title/date). `_report_bases()` returns `[cloud_reports, ~/workspace/reports]`.
## Fix (prefer A — the quick win)
- **Option A (recommended, smallest):** server-side short-TTL cache of the rendered reports listing (~90s TTL, in-process). Bounds the expensive scan to once per TTL. Leave a TODO pointing at B.
- **Option B (proper):** a `_state/reports-index.json` manifest in the cloud reports dir ({filename,title,date,type,mtime}); listing READS the manifest instead of scanning+reading 340 files; update the manifest when reports are added or on a periodic refresh.
## Constraints
- Non-breaking: full report set still listed; links still resolve. Do NOT change report SERVING (correct + fast) — only the listing build. No new traversal surface.
- Do NOT deploy live yourself — produce review-required evidence; Lucienne (controller) does the guarded deploy (`mc_orchestrator_deploy.py --apply --reload-mc`).
## Verification (before marking review-required)
- `/reports` warm response < 2s (was ~21s); report count unchanged
- A report still opens 200; `/md-view` 200; board `/` loads
- `python3 -c "import ast; ast.parse(open('app.py').read())"`; run report tests
## Terminal-state report REQUIRED: STATUS, 1-line, commit SHA, literal timing(seconds) + counts before/after, follow-ups. On error: root cause + safe-retry + stop condition. Commit incrementally; don't deploy live.
Activity
done
INTERACTIVE
Luci is working...
Details —
Done
· Medium
· Luci
▼
SState
Done
Closed
PPeople
TTiming / Details▼
api (human)
Mission Control
4d ago
4d ago
Advanced / Operator evidence
RRouting owner
ROperator console
Ticket is done; runtime is closed.MC is visibility-only. Hermes Luci launches and gates work outside MC, then mirrors evidence/status here.
WWorkflow
Start Dev Review + QA ▾
Select phases to include:
Agents
Review Gates
Decision
WAT routing: choose an agent, review gate, or decision. Buttons use the live runtime when one is attached.
Visibility-only controller routed this Luci-owned todo to internal Kanban `t_5410dc98` on board `mc-internal` (assignee codexbuilder, isolated workspace `/home/lucienne/workspace/state/kanban-worktrees/mc-4873-reports-cache`). MC remains a dumb ledger; no MC pickup/runtime/start/send/harvest endpoint was called. Luci/controller will gate review-required evidence before deploy/closure.
luci-board-manager4d ago
Controller gate passed for internal Kanban `t_5410dc98`: worker commit c53e36c was independently reviewed, cherry-picked to master as 3eceb3b8ca83eeb73265040f07edd9dfc2b67729, pushed, and deployed with MC reload. Verification: `python3 -c ast.parse(app.py)`, `python3 -m pytest -q tests/test_mc4867_reports_cloud.py` (8 passed), deploy health OK, live `/` 200, `/api/health` 200, `/reports` warm cache 0.007-0.044s after cold worker warm-up with 302 links, `/api/reports` 301 items, sample `/reports/control-room-explainer.html` 200 and sample `/md-view?...` 200. MC remains visibility-only; no MC pickup/runtime endpoint was used.