Skip to content

Fail-closed startup, view cache, and 503-until-refreshed serving path (FIX-14)#26

Merged
ChelseaKR merged 2 commits into
mainfrom
roadmap/fix-14-serving-path-lifecycle-startup-ch
Jul 12, 2026
Merged

Fail-closed startup, view cache, and 503-until-refreshed serving path (FIX-14)#26
ChelseaKR merged 2 commits into
mainfrom
roadmap/fix-14-serving-path-lifecycle-startup-ch

Conversation

@ChelseaKR

Copy link
Copy Markdown
Owner

app/server.py::_load_view re-resolved config, opened the store, and could run
a full first-run ingest inside a request; every request rebuilt
stats/wrapped/diversity/recommendations with no caching, and pyproject.toml
still omitted app/server.py from the coverage gate despite existing
TestClient tests.

  • Add a FastAPI lifespan (_lifespan) that resolves config and probes the
    store once at startup, failing closed like app.auth.AuthNotConfigured:
    raises ConfigInvalid on bad config, StoreUnavailable on an unreachable
    store. A never-refreshed store only logs a warning — it does not block
    startup.
  • Cache the built DashboardView on app.state, keyed by
    (store_path, refreshed_at stamp, hash of view-relevant config fields) via
    a new Config.view_cache_fields() helper; a request only rebuilds the view
    when the store was actually refreshed or the config actually changed.
  • Remove the inline first-run ingest from _load_view; data routes (/,
    /browse, /share, /share/card.svg) now return 503 until an explicit
    stacks refresh populates the store. No route runs ingest inline.
  • Remove app/server.py from pyproject.toml's coverage omit list (the

    =85% --cov-fail-under gate is unchanged); app/server.py now measures at
    98% coverage.

  • Add tests/test_server_lifecycle.py covering populated-store routes, the
    503 path, cache reuse/invalidation across a refreshed_at bump, and
    lifespan failing closed on bad config/store. Update test_auth.py,
    test_goals_time.py, and test_observability.py (via a new
    tests/conftest.py::seed_store_from_env helper) to seed the store
    explicitly before hitting data routes, since ingest no longer happens
    inside a request.
  • Mark FIX-14 done in docs/ideation/02-large-scale-fixes.md.

Full suite: 206 passed, 96.6% total coverage. make lint/typecheck/test all
green.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com


Backfill PR for a completed roadmap item (roadmap/fix-14-serving-path-lifecycle-startup-ch, 1 commit(s) over main). Part of the portfolio roadmap batch.

ChelseaKR and others added 2 commits July 3, 2026 09:42
… (FIX-14)

app/server.py::_load_view re-resolved config, opened the store, and could run
a full first-run ingest inside a request; every request rebuilt
stats/wrapped/diversity/recommendations with no caching, and pyproject.toml
still omitted app/server.py from the coverage gate despite existing
TestClient tests.

- Add a FastAPI lifespan (_lifespan) that resolves config and probes the
  store once at startup, failing closed like app.auth.AuthNotConfigured:
  raises ConfigInvalid on bad config, StoreUnavailable on an unreachable
  store. A never-refreshed store only logs a warning — it does not block
  startup.
- Cache the built DashboardView on app.state, keyed by
  (store_path, refreshed_at stamp, hash of view-relevant config fields) via
  a new Config.view_cache_fields() helper; a request only rebuilds the view
  when the store was actually refreshed or the config actually changed.
- Remove the inline first-run ingest from _load_view; data routes (/,
  /browse, /share, /share/card.svg) now return 503 until an explicit
  `stacks refresh` populates the store. No route runs ingest inline.
- Remove app/server.py from pyproject.toml's coverage omit list (the
  >=85% --cov-fail-under gate is unchanged); app/server.py now measures at
  98% coverage.
- Add tests/test_server_lifecycle.py covering populated-store routes, the
  503 path, cache reuse/invalidation across a refreshed_at bump, and
  lifespan failing closed on bad config/store. Update test_auth.py,
  test_goals_time.py, and test_observability.py (via a new
  tests/conftest.py::seed_store_from_env helper) to seed the store
  explicitly before hitting data routes, since ingest no longer happens
  inside a request.
- Mark FIX-14 done in docs/ideation/02-large-scale-fixes.md.

Full suite: 206 passed, 96.6% total coverage. make lint/typecheck/test all
green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	app/server.py
#	docs/audits/coverage.xml
#	docs/ideation/02-large-scale-fixes.md
#	docs/ideation/03-expansions.md
@ChelseaKR
ChelseaKR merged commit 8219baa into main Jul 12, 2026
6 checks passed
@ChelseaKR
ChelseaKR deleted the roadmap/fix-14-serving-path-lifecycle-startup-ch branch July 12, 2026 08:00
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