Handbook
AI providers and enrichment
Optional AI narratives augment the deterministic 360 report. Core pipeline outputs (data.json, metrics.json) are never modified by AI. Enrichment is stored separately as report/ai_enrichment.json inside each workspace.
Updated
Providers
| Provider | Key required | Default model | Transport |
|---|---|---|---|
cursor-agent |
No | composer-2.5 |
Local cursor-agent CLI |
anthropic |
Yes (session) | claude-sonnet-4-5 |
HTTPS api.anthropic.com |
openai |
Yes (session) | gpt-4o-mini |
HTTPS api.openai.com |
mock |
No | — | Test-only when FEEDBACK360_AI_MOCK=1 |
build_provider(settings.ai, credentials) constructs the active adapter. Missing
provider, unknown name, or missing API key raises ProviderNotConfigured with a
readable message.
Friendly errors
HTTP APIs return 200 for provider test results (ok: false is a valid
outcome). Transport and auth failures are surfaced as human messages — e.g.
401 maps to “API key was not accepted”. Configuration problems use 400 with
error text, not opaque stack traces.
Key handling (memory-only)
settings.jsonstores onlyai.providerandai.model.- API keys arrive per session via
POST /api/ai/credentialsand live in process memory only. PUT /api/settingsstripsai.api_keybefore persisting.- Keys are never written under the config directory or workspace tree.
Enrichment schema (ai_enrichment.json)
{
"schema_version": 1,
"provider": "openai",
"model": "gpt-4o-mini",
"generated_at": "2026-07-10T10:30:00+00:00",
"sections": {
"summary": {"status": "ok", "text": "..."},
"gaps": {"status": "rejected", "reason": "banned phrase"}
}
}
Sections: summary, matrix, gaps, divergence, statements, voices,
cta (seven keys matching section_summaries).
After enrichment, the static 360-report.html is re-rendered so each accepted
section shows a labeled ai-narrative block under its summary strip. Without
ai_enrichment.json, report output is unchanged.
Validation rules
Each provider response is validated before acceptance:
- Non-empty, 40–2500 characters
- At least one digit (numbers must be grounded in metrics)
- Banned phrases (case-insensitive):
peers and customers,manager's team,10 of 12,one flip,widest gap in the entire report
Rejected sections record status: "rejected" and reason. At most one
retry per section with validator feedback appended to the prompt.
Prompt contract
Per-section prompts include the deterministic section_summaries text, a
metrics slice, up to five qualitative comments, and strict instructions:
executive tone, 80–160 words, cite at least two numbers verbatim, never
attribute comments to rater groups, plain text only.
Related docs
- Studio HTTP API —
/api/ai/*endpoints - Data contract — deterministic JSON schemas
- Pipeline — parse → analyze → render stages