The whole path a request took, from the persona picker in the browser down to the structured model call and back up as rendered markdown.
A single form: pick a persona, a domain, one or more inspiration themes, the struggles the applicant has heroically overcome, and contact details.
TLS via certbot, reverse proxy to the app server. Nothing clever — it just had to not fall over at a birthday party.
Middleware — rate limit 5 req / 5 min per IP · security headers · request-id logging
Inspiration packs.
Struggle options.
The one that matters.
SPA fallback to index.html; 404s under api/*.
InspirationPack: label, brief, exemplars, keyword hints. Hand-written — this is
where the actual joke lives.
The adversity catalogue.
Prompt assembly — split so the expensive half never changes
get_system_prompt_structured plus tone instructions from the dial. Identical on every
request, so it sits at the front as a cacheable prefix.
make_user_prompt_structured — persona, domain, sampled exemplars, struggles, contact.
chat.completions.parse with response_format=ResumeGenerationOutput — a
schema, not a prose blob. Returns summary, skills, experience.
Model and reasoning settings come from config.py (there was a fast mode for the
live demo).
build_education runs off a SHA-256 seeded RNG. Degrees, certifications and awards
are deterministic — same inputs, same credentials, every time.
Model output and planned credentials merge into one typed object, then render to markdown.
On a refusal, a length stop, a content filter, or a dead API, _create_fallback_resume
builds one straight from the theme exemplars. The page never showed an error — it just got funnier
and less specific.
Every call logged through log_openai_usage — model, tokens, duration, cost