The usual AI resume flow looks like this:
old CV + job posting → LLM → improved CV
It has a basic flaw. My old CV was already a heavily trimmed version of my professional history. If I didn't think something was important and didn't write it down for ten years, the model doesn't know about it either. It can only rephrase what's already there.
I hit this while preparing for a job search. Over the last six months the way I develop software changed a lot: more and more of the mechanical work (reading a codebase, writing code, fixing, refactoring, part of the analysis) goes to AI agents. Formally I'm still a developer and tech lead, but "Android Tech Lead" describes less and less of what I actually do. So the real question wasn't how to phrase my resume. It was what job should I even be looking for next?
So I flipped the flow:
facts and context first → then AI → and only then a resume
The result is Career Portal, a private knowledge base about my own professional life. The resume turned out to be the last step.
Store the context the fact was true in
The portal keeps a profile, jobs, projects, skills and notes, and context is split by level:
- Profile: who I am and what I want.
- Job: what role I held during that period.
- Project: what I did there, with what stack, in what role, with what result.
This looks excessive until you describe several years at one company. At one employer I might have an Android project where I own the mobile app and the team, a Kotlin/Ktor BFF where I'm a backend developer and architect, and elsewhere KMP, internal tooling, CI/CD or platform work. Dump all of that into one "Work experience" field and the model mixes contexts: technology from one project lands next to an achievement from another, and a Tech Lead role spreads onto work where I was a regular developer.
The principle: it's not enough to save a fact; you need to save the context in which it was true.
There's also a private free-form "About me" field. Things like "I don't want this role anymore" or "I managed people here but don't remember the exact team size" aren't resume material yet, but they are context for the AI later. And I don't want every intermediate edit to a public CV to read as "he's job hunting again."
The most useful AI output wasn't text
After filling in the profile you can run a review. I expected the usual advice: trim, reorder, make wording stronger. Instead the agent started asking questions.
I wrote that I managed Android teams. It asked: exactly how many people? I wrote about working fully remote. It asked whether I'd consider hybrid in St. Petersburg. I listed several career directions. It asked which is a current goal and which is just an option.
At the job level it gets more uncomfortable, in a good way:
The job review (UI in Russian). Left: questions and weak spots, such as "you wrote 'sped up development several times', is there a number?" and "the Team field is empty". Right: recommendations and strengths, such as the crash-free 60% → 99.8% metric.
- "Significantly sped up development" → by how much? Did the release cycle go from six weeks to two? One release a month to four?
- "Reduced incident response time" → from what value to what value?
- "Moved development from a contractor to in-house" → team size, project scale, and what changed in timelines, cost or speed?
At the project level, one of my facts already had a clear before → after: crash-free rate went from roughly 60% to 99.8%. There was almost nothing to improve. Right next to it sat "significantly sped up development", which is clear to me because I remember the context and nearly empty to anyone reading the resume for the first time.
I always assumed metrics were mainly a manager's territory. It turned out I need them just as much to explain my own work: team size, devices in production, number of stores, releases, cycle time, error rate, operation volume. Not everything is money, but "I improved the process" and "before → after" are very different claims.
The most useful thing the AI did wasn't writing about me. It asked about the things I didn't think to write down.
Then: what can this experience even be called?
My problem wasn't phrasing Head of Mobile nicely. I wasn't sure I should be looking for Head of Mobile at all. I didn't want to pick a title and stretch a biography over it; I wanted to collect what I actually did first and see which roles follow.
The "Suggest a role" feature looks at the profile, experience, projects, stack and results, and proposes positioning options with reasons:
Role suggestions (UI in Russian). Each role gets a fit label, what to emphasize, and why it fits, citing facts from the profile.
My options included Head of Mobile, Mobile Engineering Manager, and later Lead Android Architect, Mobile Platform Lead and a few others. The AI doesn't decide who I should be. It proposes a hypothesis with arguments from my own history; I accept, edit or ignore it.
A saved role becomes a separate view of the same fact base. These aren't three versions of me, just different selections of real facts:
-
Head of Mobile: team management, hiring, moving development in-house, engineering standards, release processes. -
Lead Android Architect: Android/Kotlin, architectural decisions, stability, modernization, hands-on work. -
Mobile Platform Lead: CI/CD, platform mechanisms, feature toggles, KMP, internal infrastructure.
With one fact base and a model that isn't allowed to invent achievements, this is choosing which part of a real history is relevant, not bending a biography to a job posting.
Resume generation comes last, and publishing stays manual
After choosing a role, the portal can help search for postings in that direction and assemble a resume for the role, or narrower, for a specific posting. I deliberately avoided building it around "Am I an 82% match?". The question I want answered is: what from my actual experience needs to be shown for this resume to answer this posting's requirements? The posting becomes context for selecting facts, not a verdict on the candidate.
The result is saved as a separate resume, in the UI and as files, and the last step is manual: I decide what gets published. For career data I don't want an agent that invents a role, writes a document and sends it out with no human in between.
It isn't a programmer-only problem
Later I made the portal multi-user and loaded my wife's resume. She's an accountant. The same pattern repeated:
- How many legal entities were you handling?
- How many invoices did you issue per month on average?
- How many material write-off transactions?
- What was the monthly volume?
The mechanism has nothing to do with Android or Kotlin. A person writes "I worked on X"; the AI answers "what was the scale of X, and what backs that up?"; the person goes back to their real history and fills it in.
Stack and authorship
- FastAPI, Jinja2 and SQLite; no heavy SPA.
- The database holds a profile, jobs with nested projects, skills, education, notes, roles, generated resumes and job-posting data.
- PDF/DOCX import: text is parsed, a preview is built, and data lands in the database only after confirmation. Replacing an already filled profile needs separate confirmation.
- AI providers: Claude CLI, Codex CLI, and an OpenAI-compatible provider. Job board integration came after the first MVP.
The project kept its genesis trail. The master plan spelled out the roles: Claude in chat is the architect, Claude Code is the executor, I'm the owner. An agent wrote every line of the portal's code. I didn't write a single line, and I didn't read one either. My part was the task, the roles, the specs, and the decisions about what the product should be.
The honest result: almost nobody writes to me
I'm using the portal for a real job search. The resume is much more detailed and evidence-backed, I found plenty of gaps in my own history, added metrics, and looked at roles differently.
But there are almost no calls or messages, and I don't know why. It could be the market, my positioning, the resume itself, or I'm optimizing the wrong part of the process. One uncomfortable hypothesis: iterating on a resume with AI for a long time can land you in a local maximum, where the document gets more logical to you and the model without working better in actual hiring. I don't have data to state that as a fact.
So I don't claim the portal solved my job search. It solved a different problem: my professional history is stored separately from its publications, claims were turned into evidence, I saw several possible roles, and I can build different resumes from one fact base. Whether they work is up to the market.
Takeaway
A resume is a temporary snapshot of a career, not its storage. What matters comes earlier: facts, context, projects, real roles, scale, numbers, preferences and constraints.
If that base is weak, AI rewrites weak material nicely. If it's good, AI can find a gap, ask an uncomfortable question, suggest an unexpected positioning, and assemble different documents from the same history. What I don't hand over: deciding who I should be, inventing achievements, deciding whether to apply, and publishing the final version.
I wanted AI to write about me better. First I needed to know and prove my own professional history much better myself.
The full case study, with more screenshots of the portal, is on my site: https://hram.github.io/en/articles/career-portal/


Top comments (3)
Keeping the project context attached to each fact addresses a specific failure you describe: borrowing an achievement from one project and assigning it to a different role.
I'd give the answers to the metric questions an evidence status too: measured, approximate recollection, or unknown. "Roughly 60% to 99.8%" should keep that qualifier in every generated view, and "I don't remember the team size" should remain a gap rather than pressure to produce a number. A useful regression case would be a job posting that asks for a metric absent from the fact base: does the generated resume omit the claim and put the question back to you?
Good question, and I don't have an automated regression test for exactly that case today — here's what actually governs the behavior.
The portal works on three separate levels: Profile, Job, and Project. Each level has its own prompt, and those prompts aren't hardcoded — they're stored inside the portal and I can edit them for any need. What the portal does mechanically is: take the prepared prompt template for that level, fill it with the actual data from the fact base, and hand the filled prompt to the AI.
That means the strictness of checks, what counts as "enough evidence," how a missing metric should be handled — all of that lives in the prompt text, not in application code. If I want stricter behavior for a specific case, I extend the prompt, not the codebase.
Right now the prompts do carry hardening instructions along the lines of "don't invent," "write only from the facts given." But you're right that this isn't a 100% guarantee — a prompt instruction is a strong nudge, not a constraint the model can't violate. So the real backstop isn't the prompt, it's that the final resume is something I read and approve before it goes anywhere. The system proposes; I'm still the one who catches it if a number that isn't there sneaks in.
That makes the current boundary clear. I wouldn't try to solve it with a longer "don't invent" instruction either.
A small aid for the manual review could be a separate claim-to-source table beside the resume: each generated metric, the original fact text, and its project. An empty source cell becomes a review question, while "roughly" remains visible on both sides. The table can still be wrong and needs checking, but it gives you somewhere concrete to start instead of rereading polished prose for a plausible invented number. It would also make that missing-metric case a useful saved fixture even before you automate it.