Available Hire Me
← All Work Full-Stack + AI
Theo Mihell

Portfolio & AI Career Platform

Portfolio and private AI-assisted job-search platform sharing one YAML data model, so every application yields a tailored, evidence-backed CV.

Jekyll Python Jinja2 WeasyPrint YAML SCSS Vanilla JS GitHub Actions StatiCrypt GitHub Pages
Sector Finance / Career Platform
Role Designer, Developer & Platform Architect
Duration 2026
Team Solo
Challenge

A finance professional applying into a competitive market needs two things that pull in opposite directions. A public profile that is fast, clean and credible enough for a recruiter to skim in ninety seconds — and an operational layer that tracks every application, analyses each job advert, and tailors a CV and cover letter to it. Off-the-shelf CV builders solve neither: they emit the same document for every employer, and the underlying facts of a career end up duplicated across a dozen files that quietly drift apart.

Approach

One canonical YAML data model is the single source of truth for every fact about the candidate — thirteen files covering person, skills, employment, education, projects, achievements, timeline, brand, navigation, social links, certifications, testimonials and volunteering. The public Jekyll site, the tailored CVs, the cover letters and the interview preparation all render from that same data, and every skill claim is backed by a STAR-format evidence file. An AI-assisted workflow turns a pasted job advert into structured analysis and then into per-application CV and cover-letter data — but never into a document. Deterministic Python build scripts own the formatting, so identical input always produces an identical PDF.

Outcome

The public profile and the job-search operation now share one source of truth: changing a skill or a role updates the website, the CV, the cover letter and the interview notes at once, with no duplicated facts to reconcile. Generated documents are reproducible and fully evidence-backed, because the AI can only fill in structured data — it cannot invent a claim or alter the typography. The whole pipeline runs unattended on push, rebuilding pages, generating documents and exporting print-ready A4 PDFs.

13 YAML files Canonical data
6 AI prompts
10 STAR files Evidence library
Deterministic Document build
Technical Deep Dive

Theo Mihell — Portfolio & AI Career Platform

This is two systems that portfolio sites rarely attempt to combine. The first is a public profile a recruiter can skim in ninety seconds. The second is a private operating layer that runs the job search itself: analysing each job advert against the candidate’s real experience, tailoring a CV and cover letter to it, and preparing the material for the interview that follows.

Both render from the same data. That is the whole point of the architecture.

One data model, many outputs

Every page on the public site renders from structured YAML rather than hardcoded markup. Thirteen files in _data/ are the single source of truth — person, skills, employment, education, projects, achievements, timeline, brand, navigation, social links, certifications, testimonials and volunteering.

That indirection is what makes the second half of the brief possible. The same skills.yml that draws the skills grid on the homepage also supplies the skills section of every generated CV and the talking points in interview preparation. There is no second copy of the facts to fall out of sync, and no content page in the repository where a fact can hide from the others.

The site itself is deliberately conventional: Jekyll with eleven layouts drawn from that data, a single SCSS source file exposing its design tokens as CSS custom properties, and vanilla JavaScript for progressive enhancement only — a mobile nav toggle and a theme switch that degrades cleanly.

AI writes data, not documents

This is the design decision the platform rests on, and it is worth stating plainly: AI never produces a PDF, a Word file or a formatted document. It produces structured YAML and nothing else.

A pasted job advert becomes ai-analysis.yml — a requirement-by-requirement mapping against the candidate’s canonical data, including an honest assessment of the gaps. That analysis becomes cv.yml and cover-letter.yml. A deterministic Python build then renders those files to HTML through Jinja2 templates and to print-ready A4 PDFs through WeasyPrint.

The consequence is that the AI’s blast radius stops at the data layer. It cannot alter typography, break a page’s layout, inject a claim that no evidence supports, or produce a document that cannot be reproduced from its inputs. Identical input YAML yields an identical PDF — which is what makes AI-generated documents reviewable at all. A human reviews the YAML, not the rendering.

Generation runs at temperature 0. Interview preparation, the one place where natural phrasing genuinely helps, runs at 0.3.

Every claim is traceable

The platform will not let a CV assert something it cannot evidence. A library of STAR-format files backs the claims — situation, task, action and result, each with quantified metrics and the skill it demonstrates. Every prompt is required to cite the evidence file behind each statement in a generated document, and to flag requirements the candidate cannot evidence rather than paper over them.

The governance rules are written down and consistent across the prompt library. The AI may generate structured data, reorder highlights for ATS optimisation, and draft professional summaries. It may not invent experience or achievements. It may not edit the factual records in person.yml, employment.yml or education.yml without explicit human approval. It may not submit an application or contact an employer.

The private operating layer

Behind the public site sits a non-public area, deliberately outside the navigation, the sitemap and search indexing. It holds the job-search operation: an application tracker, general guides, the project documentation and the prompt library, organised as a hierarchy rather than a flat list of pages.

Each application is a directory, and its contents are the audit trail of that application — the raw job advert, the company research, the AI’s structured analysis, the tailored CV and cover-letter data, a status file, and interview notes. Status moves through a defined lifecycle: applied, screening, interview, then offer, rejection or withdrawal, with the outcome and any feedback recorded against it. The search therefore accumulates comparable data over time instead of a folder of forgettable submissions.

Prompts as a maintained artefact

Six prompts live in the repository as first-class files: job analysis, CV generation, cover letter generation, interview preparation, company analysis and LinkedIn content.

Each declares its role, its exact input files, its output path and a set of concrete, testable rules — and each follows the same structure, so swapping the underlying model is a configuration change rather than a rewrite. They are deliberately agent-agnostic and versioned in git rather than by filename, which keeps the prompt library reviewable in the same pull requests as the code it feeds.

Deliberate constraints

The stack is framework-free by policy, and the policy is written down: Jekyll, SCSS in a single source file, vanilla JavaScript, YAML, and Python for document generation. No SPA framework, no utility-class CSS, no database-backed CMS, no client-side rendering of primary content, no npm-heavy build tooling for the website.

The stated reason is maintainability. The site stays fast, the whole repository remains legible to any coding agent without framework-specific knowledge, and there is exactly one way to do each thing. The harder reason is that a site which renders from YAML at build time has no runtime to attack, no database to leak, and no server to keep patched.

Build and deployment

Five GitHub Actions workflows run the platform. The main pipeline regenerates the application pages, builds each application’s CV and cover letter, exports the PDFs, runs the Jekyll build, stages the generated documents, applies static encryption to the private area’s entry point, and deploys to GitHub Pages. Separate workflows validate every YAML file, spell-check the prose, build a single application’s documents on demand, and run a weekly Lighthouse audit against the live site.

Push to main is the entire interface. There is no manual deploy step and no build output committed to the repository.

Visit the Site Jekyll Jinja2 WeasyPrint GitHub Pages