Skip to content

feat(forecast): Phase 2 simulation package read path#2219

Merged
koala73 merged 5 commits into
mainfrom
feat/mirofish-phase2-simulation-rpc
Mar 24, 2026
Merged

feat(forecast): Phase 2 simulation package read path#2219
koala73 merged 5 commits into
mainfrom
feat/mirofish-phase2-simulation-rpc

Conversation

@koala73

@koala73 koala73 commented Mar 24, 2026

Copy link
Copy Markdown
Owner

Summary

Phase 2 of the WorldMonitor → MiroFish bridge. Phase 1 (PR #2204) delivered the simulation package write path. This PR delivers the read path so MiroFish (or any LLM scenario-analysis workflow) can discover and consume the package at runtime.

  • Redis existence key: writeSimulationPackage now writes forecast:simulation-package:latest to Redis after a successful R2 write, with { runId, pkgKey, schemaVersion, theaterCount, generatedAt } and 60-day TTL. Zero R2 cost for existence checks.
  • getSimulationPackage RPC: New GET endpoint /api/forecast/v1/get-simulation-package that reads the Redis key and returns the pointer metadata. Returns found: false when no package has been written yet (e.g. before the first deep forecast run).
  • Proto: GetSimulationPackage RPC + get_simulation_package.proto message definitions. make generate run to regenerate client/server types and OpenAPI spec.
  • Gateway cache tier: medium (same as get-forecasts).
  • Health monitoring: simulationPackageLatest added to STANDALONE_KEYS + ON_DEMAND_KEYS in api/health.js (WARN not CRIT when absent, since it only exists after the first deep run).
  • Tests: SIMULATION_PACKAGE_LATEST_KEY constant validation + writeSimulationPackage null-guard (returns null without R2 credentials). 2296 tests pass.

Closes todo #17.

Test plan

  • All 2296 unit tests pass
  • npm run typecheck clean
  • After a successful deep forecast run: forecast:simulation-package:latest appears in Redis with correct shape
  • GET /api/forecast/v1/get-simulation-package returns { found: false } when key absent, correct pointer when present

Post-Deploy Monitoring & Validation

  • What to monitor: forecast:simulation-package:latest Redis key after next deep forecast run
  • Validation: After a deep run completes, GET /api/forecast/v1/get-simulation-package should return found: true with pkgKey matching the R2 path
  • Failure signal: found: false after a known successful deep run indicates Redis write failed silently in writeSimulationPackage
  • Validation window: First deep forecast run post-deploy

koala73 added 2 commits March 24, 2026 21:59
…ckage RPC + Redis existence key)

- writeSimulationPackage now writes forecast:simulation-package:latest to Redis after
  successful R2 write, containing { runId, pkgKey, schemaVersion, theaterCount, generatedAt }
  with TTL matching TRACE_REDIS_TTL_SECONDS (60 days)
- New getSimulationPackage RPC handler reads Redis key, returns pointer metadata without
  requiring an R2 fetch (zero R2 cost for existence check)
- Wired into ForecastServiceHandler and server/gateway.ts cache tier (medium)
- Proto: GetSimulationPackage RPC + get_simulation_package.proto message definitions
- api/health.js: simulationPackageLatest added to STANDALONE_KEYS + ON_DEMAND_KEYS
- Tests: SIMULATION_PACKAGE_LATEST_KEY constant + writeSimulationPackage null-guard test

Closes todo #17 (Phase 2 prerequisites for MiroFish integration)
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vercel

vercel Bot commented Mar 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Mar 24, 2026 6:45pm

Request Review

@mintlify

mintlify Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
WorldMonitor 🟢 Ready View Preview Mar 24, 2026, 6:03 PM

koala73 added 2 commits March 24, 2026 22:28
… runId mismatch

- Add `error` field to GetSimulationPackageResponse: populated with
  "redis_unavailable" on Redis errors so callers can distinguish a
  healthy not-found (found=false, error="") from a Redis failure
  (found=false, error="redis_unavailable"). Adds console.warn on error.
- Add `note` field: populated when req.runId is supplied but does not
  match the latest package's runId, signalling that per-run filtering
  is not yet active (Phase 3).
- Add proto comment on run_id: "Currently ignored; reserved for Phase 3"
- Add milliseconds annotation to generated_at description.
- Simplify handler: extract NOT_FOUND constant, remove SimulationPackagePointer
  interface, remove || '' / || 0 guards on guaranteed-present fields.
- Regenerate all buf-generated files.

Fixes todos #18 (runId silently ignored) and #19 (error indistinguishable
from not-found). Also resolves todos #22 (simplifications) and #23
(OpenAPI required fields / generatedAt unit annotation).
…no-cache not-found

Three P1 regressions caught in external review:

1. Key prefix bug: getCachedJson() applies preview:<sha>: prefix in non-production
   environments, but writeSimulationPackage writes the raw key via a direct Redis
   command. In preview/dev the RPC always returned found:false even when the package
   existed. Fix: new getRawJson() in redis.ts always uses the unprefixed key AND throws
   on failure instead of swallowing errors.

2. redis_unavailable unreachable: getCachedJson swallows fetch failures and missing-
   credentials by returning null, so the catch block for redis_unavailable was dead
   code. getRawJson() throws on HTTP errors and missing credentials, making the
   error: "redis_unavailable" contract actually reachable.

3. Negative-cache stampede: slow tier caches every 200 GET. A request before any deep
   run wrote a package returned { found:false } which the CDN cached for up to 1h,
   breaking post-run discovery. Fix: markNoCacheResponse() on both not-found and
   error paths so they are served fresh on every request.
@koala73
koala73 merged commit f87c8c7 into main Mar 24, 2026
7 of 8 checks passed
@koala73
koala73 deleted the feat/mirofish-phase2-simulation-rpc branch March 24, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant