{% extends "base.html" %} {% block title %}Settings{% endblock %} {% block body %}

Settings

{% if saved %}
saved
{% endif %}
Anthropic API key {{ 'configured' if has_key else 'missing' }}
Models per role {% for role, spec in roles.items() %} {% endfor %}
RoleModelEffort (ignored on Haiku)
{{ spec.label }} {{ role }}
Owner
Claude Code sessions
GitHub {{ 'token configured' if has_gh_token else 'no token' }}
How to create it: GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token (classic).
  • Scope: check only repo. GitHub has no read-only scope for private repositories; Pythia only does reads (GET).
  • Organization SSO: if the organization uses SAML SSO, after creating the token click Configure SSO → Authorize on the organization (e.g. acme-corp). It is a one-time step; changing allowlisted repositories later needs no new approval.
  • Expiry: choose an expiration; when it expires, Pythia shows the error in Sources and you paste a new one here.
How to create it: GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens.
  • Resource owner: the repositories' organization (e.g. acme-corp). If the organization requires approval, the token only works after it is approved — and again at every change of repositories.
  • Repository access: only the allowlisted repositories.
  • Repository permissions (all Read-only): Pull requests, Issues and Metadata.

Changing these lists retracts what fell outside and re-reads what holds again.

Slack {{ 'token configured' if has_slack_token else 'no token' }}
Which token to use: the User OAuth Token (starts with xoxp-) of the Slack app already approved by the admin — at api.slack.com/apps → your app → OAuth & Permissions. Pythia reads as you, with no bot.
  • User Token Scopes (read-only): users:read and, for each kind of conversation you want to read, public channels channels:read + channels:history; private groups:read + groups:history; DMs im:read + im:history; groups mpim:read + mpim:history.
  • No write scope. If any is missing, Sources shows which.

On every read, the last revision days are re-read in full: an edit retracts the previous version and a deleted message is deleted here too. Edits older than that are not seen; new replies on old threads are seen as long as the thread had a reply within the watch days.

Changing these lists retracts what fell outside and re-reads what holds again.

Confluence {{ 'token configured' if has_cf_token else 'no token' }}
How to create it: id.atlassian.com → Security → Create and manage API tokens → Create API token with scopes.
  • App: Confluence. Scopes (all read): {% for sc in cf_scopes %}{{ sc }}{{ ', ' if not loop.last }}{% endfor %}.
  • The scope covers all of Confluence: changing spaces and trees on the allowlist needs no new token. When it expires, Sources shows the error.
How to create it: id.atlassian.com → Security → Create and manage API tokens → Create API token. It can do everything your account can; Pythia only reads.

A page edit does not erase what came from the previous version: it stays as history, and the adjudicator decides whether each claim still holds, evolved or was wrong. A page deleted in Confluence disappears from here too.

Narratives

The narrative pass is the most expensive synthesis (only the affected narratives go in full). Fewer passes = slightly more outdated narratives and less spend; meanwhile, Evolution shows the page as "updating". Today: {{ nar_today.n }} pass(es), US${{ '%.2f'|format(nar_today.usd|float) }}.

Drift sweep

The sweep reviews entities in rotation (what has gone longest without review, the most consulted, and documentation with newer activity in another source), reading GitHub and Confluence live. It only accuses: the adjudicator decides. Today: US${{ '%.2f'|format(sw_spent) }} spent.

incident.io catalog {{ 'key configured' if has_inc_key else 'no key' }}
Which key to create: an API key at incident.io → Settings → API keys.
  • Permissions: catalog read only — View catalog types (catalog_types.view) and View catalog entries (catalog_entries.view).
  • No write, incident, alert or on-call permission.

Changing this list re-reads the catalog: what went away is retracted, and what stays the same does not go through the LLM again.

{% for t, e in inc.types.items() %}{% endfor %}
{{ t }}
Push (briefing by hook)

They tell the AI when to use Pythia (the "how" is in the MCP tool descriptions). They go at the start of each conversation and after /clear or compaction. Keep them short: too many rules make agents worse. {owner} becomes your name.

Your team

Used in the repositories' "you or your team" mode. This list is the truth; importing from the catalog only copies, it never syncs by itself.

{% for m in team %}{% set i = loop.index0 %} {% for k in ['name','email','slack','github','jira','zoom'] %}{% endfor %} {% endfor %} {% for k in ['name','email','slack','github','jira','zoom'] %}{% endfor %}
NameEmailSlackGitHubJiraZoomRemove
{% if catalog_teams %}
{% else %}

Import becomes available once the incident.io catalog is synced.

{% endif %}

Claude Code integration

MCP (pull) — run once in the terminal:

claude mcp add --scope user --transport http pythia http://127.0.0.1:{{ port }}/mcp/

Hooks (push) — add to ~/.claude/settings.json:

{{ hooks }}
{% endblock %}