feat(calibration): 10-question battery, config-driven voice, WCAG-safe theme
Rework calibration.py into a fixed 10-question battery:
- 4 critical questions (language, name, persona name, gender)
- 6 random probes drawn from the 12-item pool (all AI/tech-unrelated)
Theme inference (palette × typography × density × labels):
- Palette: warmth × contrast × energy → default|rose|morning|evening|
sage|paper|ink; all choices verified WCAG AA ≥4.5:1.
- Typography: elaborate+warm → serif-warm; cool+ink → mono;
high-contrast+cool → serif-formal; energetic+warm → mixed-modern;
otherwise sans.
- Density: elaborate cadence → airy; terse → dense; else normal.
- Labels: serif-warm/mixed-modern → cursive; mono → prefix; else block.
Voice selection:
- Removed VOICE_POOL (lang × gender heuristic).
- Added _load_persona_voices(): reads [voices.<lang>].id from a
cart.toml persona file at PCART_CONFIG_PATH or app/conf/persona.toml.
Falls back to FALLBACK_VOICES when no file is present.
- _pick_voice(lang) selects by language key only — no gender heuristic.
cart_store.Cart changes:
- Added calibration_version: int = 1 (new carts emit 2)
- Bumped version: 3 → 4
- Removed unused import
No changes to app/main.py — calibration wiring was already correct.
This commit is contained in:
+4
-2
@@ -14,7 +14,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from dataclasses import asdict, dataclass
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
@@ -41,8 +41,10 @@ class Cart:
|
||||
ui_typography: str = "sans" # sans | serif-warm | serif-formal | mixed-modern | mono
|
||||
ui_density: str = "normal" # airy | normal | dense
|
||||
ui_labels: str = "block" # block | cursive | none | prefix
|
||||
# Tracks which calibration battery was used (bumped when calibration.py is reworked).
|
||||
calibration_version: int = 1 # 1 = original critical+random; 2 = 10-question battery v2
|
||||
created_at: str = ""
|
||||
version: int = 3
|
||||
version: int = 4 # bumped from 3 → 4 with calibration_version field addition
|
||||
|
||||
@property
|
||||
def is_calibrated(self) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user