You're offline — showing cached data

MC-4867

Migrate MC reports to cloud (PKA-Outputs) — cloud-first + workspace fallback [non-breaking]
2026-06-13 07:35:36 SAST
Home Board MC-4867

Migrate MC reports to cloud (PKA-Outputs) — cloud-first + workspace fallback [non-breaking]

## Goal Migrate Mission Control's report store from `~/workspace/reports` to the shared cloud outputs tree on Google Drive (`PKA-Outputs/reports`, reachable on Luci at `/home/lu...
State Done Next Action Closed Owner Luci Runtime Closed Age 4d ago
MC-4867
Ticket is done; runtime is closed. · profile claude_opus_1m_high

Description

MC-4867
## Goal Migrate Mission Control's report store from `~/workspace/reports` to the shared cloud outputs tree on Google Drive (`PKA-Outputs/reports`, reachable on Luci at `/home/lucienne/gdrive/PKA-Outputs/reports` via the rclone mount `gdrive-mount.service`). MC must keep serving reports the ENTIRE time — NON-BREAKING. ## Background The PKA repo already migrated dashboards/reports/outputs to `PKA-Outputs/` on GDrive; the PKA dashboard server (Mac) now serves cloud-first with repo fallback (commit 0fdc637f). This ticket does the Luci/MC half. Plan: `~/workspace/PKA/docs/plans/2026-06-05-outputs-to-cloud-storage-split.md` + checklist `docs/plans/2026-06-09-outputs-migration-checklist.md`. Resolver: `python3 ~/workspace/PKA/pka_paths.py outputs-dir reports` prints the host-correct cloud dir (on Luci = `/home/lucienne/gdrive/PKA-Outputs/reports`). Verify the mount first: `ls /home/lucienne/gdrive/PKA-Outputs/reports`. ## Changes — mission-control/app.py 1. `REPORTS_DIR = WORKSPACE / "reports"` (line ~4514). Add a cloud-first resolver mirroring the PKA pattern: a helper returning `[cloud_reports_dir, WORKSPACE/'reports']` (cloud only if the mount exists). The `/reports/<file>` route (~4728), `/md-view` reports branch, the report LISTING globs (~4646, 4664, 4906), and the DELETE/pdf/convert handlers (~4778/4793/4860) must resolve per-file CLOUD-FIRST then workspace fallback. - Listing: scan BOTH bases, dedupe by filename, cloud wins. - DELETE: move the file to `_deleted/` within the SAME base it lives in (no cross-device rename). - PRESERVE every existing security check: reject `..`, `str(fpath).startswith(str(base.resolve()))`, and the suffix allow-list. Do not weaken them. 2. Migrate existing files: copy `~/workspace/reports/*` (html/md/assets, but EXCLUDE the `radio/` subdir — that is Ticket 2) into `/home/lucienne/gdrive/PKA-Outputs/reports/`, preserving subdirs. Parity-check file counts before/after. 3. Repoint Luci report-WRITER skills that write to `~/workspace/reports/`: audit with `grep -rn "workspace/reports" ~/.claude/skills`, then update `deep-research` and `research-brief` (and any others found) SKILL.md write steps to target the cloud reports dir via the resolver `python3 ~/workspace/PKA/pka_paths.py outputs-dir reports --ensure`. (~/.claude is a SEPARATE git repo — commit + push there.) 4. Reload MC SAFELY: this is the LIVE control plane. Validate app.py parses (`python3 -c "import ast; ast.parse(open('app.py').read())"`) BEFORE any reload. Use the guarded deploy path (mc_orchestrator_deploy.py) if applicable; re-verify branch state at land time. DO NOT take MC down (the MC-3725 lesson). ## Verification — ALL must pass before done - urllib GET `http://127.0.0.1:3001/reports/<an existing report>.html` -> 200 - A report you migrated to cloud serves 200 AND a workspace-only one still serves 200 (fallback works) - `/md-view?file=reports/<file>.md` -> 200 - Reports listing page renders the FULL set (no drop in count vs before) - MC board http://127.0.0.1:3001/ still loads; gunicorn not crashed; `tail` MC logs clean - Path traversal `/reports/../app.py` still rejected (400/404) ## Hard constraints - NON-BREAKING: cloud-first + workspace fallback so MC serves regardless of cloud state. - Preserve all security checks in serve_report. - Do NOT touch radio/mp3 handling (Ticket 2). - Touch ONLY report-serving code + the named writer skills. No scope creep. ## Terminal-state report (REQUIRED) End with: STATUS (success|warning|error), 1-line summary, commit SHA(s) for both repos, the literal verification HTTP codes, and follow-ups. On error: root cause + safe-retry + explicit stop condition. Commit artifacts incrementally. Lucienne (Mac) will review the diff + re-verify before this is closed.

Activity

done
Luci is working...
Live
No activity yet
Help