Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,14 @@ SUS can be configured two ways:
| App repo URL | `/setup` | `--set gitRepo.url=...` |
| Anthropic API key | `/setup` | K8s secret `sus-anthropic-api-key` |
| Git access token | `/setup` | K8s secret `sus-git-token` |
| Claude model for build sessions | — | `--set buildPod.claudeModel=sonnet` (aliases like `sonnet`/`opus`/`haiku` track the latest model; a full ID pins one) |
| Claude model for build sessions | — | `--set buildPod.claudeModel=opus` (default; aliases like `opus`/`sonnet`/`haiku` track the latest model, a full ID pins one — see note below) |
| Build pod resources | — | `buildPod.resources` in `values.yaml` |
| Landing page resources | — | `landing.resources` in `values.yaml` |

See [`charts/sus/values.yaml`](charts/sus/values.yaml) for all Helm values.

**Build-session model:** the default is `opus` (Claude Opus 5) — Anthropic's recommended model for agentic coding, so the best build quality. It costs roughly **2.5× more per token** than `sonnet` and responds a bit slower. If you'd rather trade some build quality for lower cost and faster responses, set `--set buildPod.claudeModel=sonnet` (Claude Sonnet 5). Aliases track the latest model in each family; pass a full ID like `claude-opus-5` to pin a version.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ~2.5× multiplier is now hardcoded in two places (here and charts/sus/values.yaml:42), and the PR description sources it from introductory pricing — which by definition changes. Derived numbers like this rot silently, and a stale cost ratio in the README is the kind of thing an operator makes a budget decision on.

Consider keeping the qualitative tradeoff (Opus costs more and is a bit slower) and linking to Anthropic's pricing page for the actual numbers, rather than restating a specific ratio in two files.

Note: I wasn't able to independently verify the $5/$25 vs $2/$10 figures in this environment (no network access granted for the pricing docs), so I'm flagging the durability of the claim rather than disputing its accuracy. The model IDs and aliases do check out — opus and claude-opus-5 are both valid, and using the alias to auto-track future releases is the right call for the stated goal.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to reach Anthropic's pricing docs on this run, so I can put a number on the durability concern from the last round rather than just flagging it.

The ~2.5× figure is correct today and expires on a known date:

input output
Claude Opus 5 $5 / MTok $25 / MTok
Claude Sonnet 5 — through Aug 31, 2026 $2 / MTok $10 / MTok
Claude Sonnet 5 — from Sep 1, 2026 $3 / MTok $15 / MTok

So 2.5× holds for about another month, then becomes ~1.67× — the Sonnet 5 introductory window ends Sept 1, and Opus 5 pricing is unchanged. That number is now stated in three places (here, charts/sus/values.yaml:41, and charts/sus/templates/NOTES.txt:17), and the NOTES one is printed to operators on every install and upgrade, so a stale ratio there will be actively misleading rather than just wrong-in-a-doc.

Suggest dropping the specific multiplier and linking instead, so there's nothing to update on Sept 1:

Suggested change
**Build-session model:** the default is `opus` (Claude Opus 5) — Anthropic's recommended model for agentic coding, so the best build quality. It costs roughly **2.5× more per token** than `sonnet` and responds a bit slower. If you'd rather trade some build quality for lower cost and faster responses, set `--set buildPod.claudeModel=sonnet` (Claude Sonnet 5). Aliases track the latest model in each family; pass a full ID like `claude-opus-5` to pin a version.
**Build-session model:** the default is `opus` (Claude Opus 5) — Anthropic's recommended model for agentic coding, so the best build quality. It costs meaningfully more per token than `sonnet` and responds a bit slower; see [Anthropic's pricing](https://claude.com/pricing#api) for current rates. If you'd rather trade some build quality for lower cost and faster responses, set `--set buildPod.claudeModel=sonnet` (Claude Sonnet 5). Aliases track the latest model in each family; pass a full ID like `claude-opus-5` to pin a version.

If you'd rather keep the concrete number (it is more persuasive than "meaningfully more"), that's a fine call — but then it's worth a note that it needs revisiting after Aug 31, 2026.


### Ingress

SUS includes an optional Ingress resource. Enable it in your Helm values:
Expand Down
4 changes: 2 additions & 2 deletions build-pod/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ set -euo pipefail
# APP_TEAM — the team this app belongs to
# APP_SLUG — the app's short name
# ANTHROPIC_API_KEY — API key for Claude Code
# CLAUDE_MODEL — Claude model for the session (default: sonnet)
# CLAUDE_MODEL — Claude model for the session (default: opus)
# ---------------------------------------------------------------------------

# --- Git configuration ----------------------------------------------------
Expand Down Expand Up @@ -258,4 +258,4 @@ with open(path, "w") as f:
PYEOF

exec ttyd --port 8080 --writable --base-path / \
bash -c "cd '$APP_DIR' && exec claude --dangerously-skip-permissions --model '${CLAUDE_MODEL:-sonnet}'"
bash -c "cd '$APP_DIR' && exec claude --dangerously-skip-permissions --model '${CLAUDE_MODEL:-opus}'"
6 changes: 6 additions & 0 deletions charts/sus/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ To access the landing page locally, run:
kubectl port-forward -n {{ .Values.namespaces.platform }} svc/{{ include "sus.fullname" . }}-landing {{ .Values.service.port }}:{{ .Values.service.port }}

Then open http://localhost:{{ .Values.service.port }} in your browser.

Build sessions use the "{{ .Values.buildPod.claudeModel }}" Claude model.
{{- if eq .Values.buildPod.claudeModel "opus" }}
This is Claude Opus 5 — best build quality, but ~2.5x the per-token cost of
"sonnet" and a bit slower. Set --set buildPod.claudeModel=sonnet to lower cost.
{{- end }}
Comment on lines +15 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addresses the visibility gap from the last round — NOTES is printed on helm upgrade as well as install, so upgrading operators now see the change. Good.

One gap in the guard: eq ... "opus" matches only the bare alias. Both this file and README.md:135 tell operators to pass a full ID like claude-opus-5 to pin a version — and I confirmed that path renders fine (--set buildPod.claudeModel=claude-opus-5SUS_CLAUDE_MODEL: "claude-opus-5"), but it silently skips the cost note. So the operator who was deliberate enough to pin Opus is the one who doesn't get told what Opus costs. Same for claude-opus-5[1m].

A substring check covers both spellings. The default "" keeps it safe if claudeModel is nil (a values override with a bare claudeModel: key yields nil, and contains on nil errors — eq tolerates it, so this is only needed once you switch to contains):

Suggested change
Build sessions use the "{{ .Values.buildPod.claudeModel }}" Claude model.
{{- if eq .Values.buildPod.claudeModel "opus" }}
This is Claude Opus 5 — best build quality, but ~2.5x the per-token cost of
"sonnet" and a bit slower. Set --set buildPod.claudeModel=sonnet to lower cost.
{{- end }}
Build sessions use the "{{ .Values.buildPod.claudeModel }}" Claude model.
{{- if contains "opus" (default "" .Values.buildPod.claudeModel) }}
This is Claude Opus — best build quality, but several times the per-token cost
of "sonnet" and a bit slower. Set buildPod.claudeModel=sonnet to lower cost.
{{- end }}

Two smaller things folded into that suggestion:

  • "Set --set buildPod.claudeModel=sonnet" reads as a stutter, and --set is wrong for the operators who use a values file. Bare buildPod.claudeModel=sonnet works for both audiences.
  • "This is Claude Opus 5" is asserted unconditionally, but the whole point of the alias is that it tracks future releases — the day Opus 6 ships under the opus alias this line is wrong with no code change. Dropping the version number keeps it true. (Same reason I'd drop the 2.5x here — see the README comment; the Sonnet 5 introductory rate ends Aug 31, 2026, after which the real ratio is ~1.67×.)

{{- if .Values.auth.enabled }}

Authentication (Authelia) is ENABLED. The chart deploys Authelia and switches the
Expand Down
10 changes: 7 additions & 3 deletions charts/sus/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ buildPod:
repository: ghcr.io/dev-dull/sus-build
tag: latest
pullPolicy: Always
# -- Claude model for build sessions. Aliases like "sonnet", "opus", and
# -- Claude model for build sessions. Aliases like "opus", "sonnet", and
# "haiku" resolve to the latest model in that family; a full model ID
# (e.g. "claude-sonnet-5") pins a specific version.
claudeModel: sonnet
# (e.g. "claude-opus-5") pins a specific version.
# Default "opus" (Claude Opus 5) — Anthropic's recommended model for agentic
# coding, i.e. the best build quality. It costs ~2.5x more per token than
# "sonnet" and is a bit slower; set claudeModel: sonnet to trade some build
# quality for lower cost and faster responses.
claudeModel: opus

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing a default means every operator who runs helm upgrade without reading the diff gets a ~2.5× per-session cost increase with no signal. That's the one thing I'd want mitigated before merge.

SUS spins up a pod per session running claude --dangerously-skip-permissions for an interactive, long-lived session (ttyd stays connected, auto-commits every 5 min), and there's no token cap or per-session spend limit anywhere in the repo — so the downside per session is unbounded, while the "better first-shot success reduces total spend" argument is plausible but unmeasured. That asymmetry is a fine call to make deliberately; it just shouldn't be invisible.

templates/NOTES.txt already exists and already uses this exact pattern for auth (surfacing active config plus WARNING: lines). Surfacing the resolved model there costs two lines and makes the change visible at install/upgrade time:

Build sessions use Claude model: {{ .Values.buildPod.claudeModel }}
  (set buildPod.claudeModel=sonnet for lower cost / faster responses)

Worth a note in the release notes too, since the cost delta lands on existing installs rather than new ones.

ports:
terminal: 8080
preview: 3000
Expand Down
2 changes: 1 addition & 1 deletion landing/app/pods.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def _pod_manifest(
client.V1EnvVar(name="SUS_API_URL", value="http://sus-landing.sus.svc.cluster.local"),
client.V1EnvVar(
name="CLAUDE_MODEL",
value=os.environ.get("SUS_CLAUDE_MODEL", "sonnet"),
value=os.environ.get("SUS_CLAUDE_MODEL", "opus"),
),
client.V1EnvVar(
name="ANTHROPIC_API_KEY",
Expand Down
Loading