Skip to content

Shank Runbook

Shank does not deploy on its own. Every shank change is shipped as part of a sirloin deploy because the exported HTML is embedded into the sirloin binary at compile time (//go:embed in apps/sirloin/internal/pkg/emails/client.go).

Release a template change

1. Edit the template

Work in apps/shank/react-templates/emails/<name>.tsx. Validate visually with pnpm dev (see shank-local-dev.md).

2. Export to sirloin

From apps/shank/react-templates/:

Terminal window
pnpm install # only if dependencies changed
pnpm export

This writes apps/sirloin/internal/pkg/emails/templates/<name>.html.

3. Verify the diff

Terminal window
git status apps/sirloin/internal/pkg/emails/templates/
git diff apps/sirloin/internal/pkg/emails/templates/<name>.html

Sanity-check:

  • Placeholder tokens ({{CHARACTER_NAME}}, etc.) appear unchanged.
  • No accidental absolute file paths in the HTML.
  • No new <script> tags (gmail strips, others may flag).

4. Update sirloin substitution if needed

If you added or renamed a placeholder, update the matching strings.ReplaceAll call in apps/sirloin/internal/pkg/emails/client.go and add or adjust the Send* method signature so callers pass the new field. Rebuild sirloin (go build ./... from apps/sirloin/) to catch compile errors.

5. Commit both apps together

A single PR should touch both apps/shank/react-templates/emails/* and apps/sirloin/internal/pkg/emails/templates/* (and client.go if the substitution surface changed). This keeps the source TSX and the exported HTML in lockstep — reviewers can confirm the export is current.

6. Test send (preview-only)

There is no first-class shank “test send” flow. To verify end-to-end:

  • Local: run sirloin against a test SMTP (e.g. Mailpit on localhost) and trigger the worker that calls SendTrainingDone. Sirloin’s SMTP client reads SIRLOIN_EMAIL_HOST, SIRLOIN_EMAIL_PORT, SIRLOIN_EMAIL_USER, SIRLOIN_EMAIL_PASSWORD, SIRLOIN_EMAIL_SENDER (apps/sirloin/internal/pkg/env/variables.go); point them at the local SMTP. TODO(@zen): pick a canonical local SMTP image (Mailpit / MailHog / etc.) and add it to the sirloin local-dev doc.
  • Staging: deploy sirloin to staging and use a @foxy.ai test account (which bypasses some rate limits per security-model.md) to trigger a real training-completion event.

7. Deploy sirloin

Follow the sirloin deploy runbook. Shank itself has nothing to deploy.

Rollback

Because shank changes ship inside the sirloin binary, rollback = revert the sirloin commit (or redeploy the previous sirloin image). There is no shank-side rollback knob.

If a bad template is already in production:

  1. Revert the PR (or the relevant templates/<name>.html change) on main.
  2. Re-export from the reverted TSX (pnpm export) only if the revert did not bring back the previous HTML in lockstep.
  3. Build and redeploy sirloin.

For an urgent stop-gap that does not require a redeploy, sirloin operators can disable the calling worker path (e.g. skip SendTrainingDone in checkmediageneration.go) — see sirloin’s runbook.

Observability

Shank emits no telemetry. Delivery success/failure is observable through sirloin’s logs (log/slog → OTLP) and Sentry (sentry-go). Search for failed to send email or failed to get user email strings from apps/sirloin/internal/pkg/emails/client.go. See docs/src/content/docs/operations/observability.md for the sirloin logging stack.

There is no per-template delivery counter today — apps/sirloin/internal/pkg/emails/client.go returns wrapped errors and the calling worker (apps/sirloin/internal/app/worker/checkmediageneration.go) emits a failed to send training done email log line on failure, with no metric. TODO(@zen): decide whether to add a per-template counter in sirloin’s emails package; it would help post-launch verification of new templates.

Pre-release checklist

  • TSX renders cleanly in pnpm dev (no console errors).
  • pnpm export produced exactly the templates you changed.
  • All {{TOKEN}} placeholders match a ReplaceAll in apps/sirloin/internal/pkg/emails/client.go.
  • Sirloin compiles (go build ./...).
  • PR includes both shank source and sirloin exported HTML.
  • Manual preview screenshot attached for design review.