feat: legibility — conditions, hints, kinder errors (Workstream B)

GET /api/conditions surfaces what the backend already computes: moon
phase, veil thinness, geomagnetic state — junk lon degrades to moon-only
instead of a 422, missing NOAA data means fewer lines, never an error.
VeilConditions renders it in the séance side column, polling every 10 min.

ModeHint: one in-fiction line per mode after 15s of an unused sensor,
dismissed forever via localStorage. Error copy in evp/radio now
detect-and-redirects (mic denied -> 'the board needs no ear'; no WebUSB
-> try EVP) instead of dead-ending.

No geolocation prompt from the conditions strip — asking for location
from a passive readout would be hostile; ?lon= stays supported for
callers that have it.

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

# Conflicts:
#	frontend/src/pages/SeancePage.tsx
This commit is contained in:
Indiana
2026-07-28 19:19:44 +00:00
13 changed files with 579 additions and 4 deletions

View File

@@ -13,6 +13,7 @@ from app.config import settings
from app.db import Base, async_session_maker, engine
from app.routes.auth import router as auth_router
from app.routes.codex import router as codex_router
from app.routes.conditions import router as conditions_router
from app.routes.device import router as device_router
from app.routes.inventory import router as inventory_router
from app.routes.seances import router as seances_router
@@ -96,6 +97,7 @@ async def lifespan(app: FastAPI):
app = FastAPI(title="Quantumancy", lifespan=lifespan)
app.include_router(auth_router)
app.include_router(codex_router)
app.include_router(conditions_router)
app.include_router(device_router)
app.include_router(inventory_router)
app.include_router(seances_router)