/** Same-origin backend contracts required by the HUX-09 frontend. */ export const API_VERSION = "hux.v1"; export const ACCEPT = "application/vnd.hermes.hux+json; version=1"; export const EVALUATION_SCHEMA = "hux.suggestion_evaluation.v1"; export const DECISION_SCHEMA = "hux.suggestion_decision.v1"; /** * POST /hux/v1/onboarding/evaluate * POST /hux/v1/onboarding/suggestions/{sug_id}/decisions * * Evaluate accepts only schema, session_id, conversation_id and the exact * trigger. Identity MUST NOT be accepted from browser storage, query * parameters, or request bodies; derive it from the authenticated session. * The server verifies that both opaque ids belong to that identity and surface. * * Before returning a candidate, evaluation MUST atomically apply never_again, * max_shows and cooldown_seconds from suggestion.schema.json, increment shows, * and bind a single-use claim_id to identity + session + conversation + trigger. * If no_store is active, the server MUST NOT write suppression state and * returns suggestion/state/claim_id as null. Memory suggestions require the * hux.privacy capability and memory_suggestions_allowed=true. * * Decisions accept only schema, session_id, conversation_id, claim_id, * suggestion_id, expected_shows and decision. The server rechecks the claim * binding and returns 409 for stale/replayed claims. A decision never performs * the suggested action; it only persists dismiss, never-again, or acted state. */ export const BACKEND_ENDPOINTS = Object.freeze({ evaluate: "/onboarding/evaluate", decision: "/onboarding/suggestions/{sug_id}/decisions", });