agent_panel: alerts use the macro persona's verdict; all 4 takes still logged

agent_panel.verdict_source defaults to "macro": the macro take's stance is the
verdict, the synthesizer call is skipped (4 LLM calls per panel instead of 5);
"chair" restores the four-voice consensus + OPPOSE guard. Verdict source is
cached per mode and logged (panel_verdict_source). 406 tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FC4s6VCURFte4dub4xKxYL
This commit is contained in:
Harwinder Sekhon
2026-09-03 21:16:45 -04:00
parent d681027b20
commit b8f903ad0e
9 changed files with 175 additions and 26 deletions
+6
View File
@@ -98,6 +98,7 @@ _KNOWN_AGENT_PANEL = {
"enabled", "telegram", "dashboard", "min_quality",
"max_panels_per_day", "reuse_ttl_seconds",
"candles_enabled", "candle_bars_primary", "candle_bars_confirm",
"verdict_source",
}
_KNOWN_MARKET_OUTLOOK = {"enabled", "telegram", "max_per_day", "candles_bars"}
_KNOWN_SIGNAL_LOG = {"enabled", "path", "log_blocked_scans"}
@@ -315,6 +316,11 @@ def load_app_config(path: str = CONFIG_PATH) -> AppConfig:
raise AppConfigError(
f"config.json: agent_panel.{key} must be an integer "
"between 1 and 100")
if "verdict_source" in panel and panel["verdict_source"] not in \
("macro", "chair"):
raise AppConfigError(
'config.json: agent_panel.verdict_source must be "macro" or '
'"chair"')
app.agent_panel_settings = dict(panel)
outlook = raw.get("market_outlook", {})