Two months ago I ended a post in the middle of a build. I had spent a weekend making myself a resume as software, then gone looking at what someone without that weekend actually gets. I said I was architecting a service for the people the free tools reach least, and that I would write it down as it took shape. It is built. It is live at rung.guru, free and without an account, and this post is the part I owe that one.

Not the announcement, the accounting. Here is what I got wrong. I assumed the hard part would be the resume. The structured information, the typography, the quiet machinery that turns the two into a clean downloadable document. That took days. The first empty field took the rest of the two months.

What an empty field asks of someone

The resume I made for myself is a structured file I fill in by hand, which is a field, a label and a cursor wearing a different hat. It works well enough when you already know what a strong line looks like. I had written a few, so it worked for me, and it took me longer than it should have to notice that this was the only reason it worked.

The tell was sitting in that post and I did not read it properly at the time. Public libraries still run resume clinics, staffed by people who sit beside someone one at a time. I read that as evidence of demand. I now think it says something more particular. Much of what those staff give is not formatting help. It is the asking. Once somebody has been asked a question they can answer, the typing is the easier half.

So the thing I built asks. Situation-aware intake opens on where the person actually is, in its own plain words, recently lost a job, coming back after time away, first job, new to this country, and the questions and the resume format follow from that. Skill help proposes grounded skills to affirm, so nobody faces a blank list your skills line. Most steps are answered by choosing from options, so nothing depends on writing skill. Rung's accessibility page states the intent more plainly than I would, that it exists for people who find reading, typing, or forms hard, so accessibility is not a feature added on top, it is what the product is.

Even the opening question assumed too much, because it asks for a job title and plenty of people do not carry one. Word matching answers somebody who types cashier and has nothing to say to somebody who says they fix people's furnaces when they break down, which is closer to how people describe their own work out loud. So a second lookup sits beside the first and matches by meaning across the same thousand occupations. It recalls and never decides. When a title is too broad or matches nothing, the person narrows by field and role, browses the full list, or says none of them fit, and Rung grounds on nothing instead of guessing.

Here is the product's own demonstration reel, a stubbed journey that covers the main steps and the flow between them.

One occupation, start to finish, played from a stand-in answer set. The questions arrive one at a time, most answers are taps, and the draft builds up as they are answered.

The same answers produce more than the one document. The last post argued that the cover letter is the part the free tools help with least, and the part most worth solving, and it is in there, an optional grounded letter tailored to a job posting the person pastes in. Both leave as a real PDF and an editable Word file.

Helping without inventing

Asking the questions solves one problem and raises a harder one. As soon as a system helps somebody describe their work, it is a short step from describing work they did not do. A model asked to make a stranger sound employable can drift toward flattery without anyone intending it, and on a resume flattery and invention are not far apart.

So the rule everything else is built around is that it does not invent anything about the person. Occupation grounding takes what someone says about their work, maps it onto one of around a thousand occupations from a public government list, and offers that occupation's true duties and skills to keep. Once the occupation is settled those come out of committed data by lookup, and a test fails the build if a model is called at that step.

The writing help is fenced the same way. A rewritten line has to share a content word with what the person actually said. A number the person did not give is removed before the line reaches them, whether it arrived as a digit or as a word like doubled or hundreds. Numbers, credentials, employers, dates, results and experiences enter the resume only when they come from the person. The terms of use say it in one line, that a resume must describe your real work honestly, and that Rung is built to help with that, never to invent experience.

A resume is a claim someone has to stand behind in a room. A sentence they did not earn is not a kindness to them. It is a risk they did not agree to take.

One check runs the other way. The relevance check reads the document the person is looking at and gently flags a line that does not read like a real resume entry, then names which of six problems it thinks it found, a typo, words not readable yet, placeholder text, something that may not belong on a resume, something worth a second look, or a line that reads unclear. It will not flag a line for being short, plain, humble or unusual, and it never judges whether the work fits the job being chased, because a career changer's real past is not irrelevant. It marks, it says why, and it stops there. Nothing is blocked, nothing is silently rewritten, and the wording invites a fix without scolding. Then every download asks the person to confirm the document is theirs and true, with the box unticked every time.

That constraint costs something. A grounded line is often plainer than the one a model would write if you let it off the leash. I also suspect the reasoning travels beyond resumes. A lot of what is shipping now writes on somebody's behalf into a document that carries consequences for them, and I have started finding the more useful question to be less how good the writing is and more what the system is unable to say.

The last word is yours

A tool that will not invent has to hand back real control somewhere, or the restraint is just a smaller box. So the finished document is the person's to shape, and the heading above is the title of the screen where that happens.

Styling comes first, and it is not one bundled template. Color, Columns, Font, Spacing and an optional Photo where the market expects one, each its own choice, with the live preview redrawing as they go. The four font pairings were picked so the heading and body families stay distinct and render the same on a Mac and on Windows, which is what keeps the preview honest about the file, and one of them is set in Atkinson Hyperlegible, drawn for low vision. Pronouns show or stay hidden, sections are kept or put away, and the resume can be produced in a different language from the one the tool is being read in.

Then the handover. An Edit switch puts a pencil on everything the document can show, the name, the contact line, the summary, every bullet, every job title and date, education, languages, and the section headings themselves. A pencil appears only where editing genuinely works, so none of them are dead, and the pencils and marks are stripped before the file prints. Turn Edit off and the page becomes exactly how an employer will see it. Everything before that screen is the machine's best offer. That screen is where the person overrules it.

The phone was the design, not a breakpoint

The other gap the last post named was that this had to work well on an inexpensive phone held in one hand, not as a shrunken copy of a desktop screen. That turned out to shape the architecture more than the layout.

There is no account, and nothing to install. The answers and the draft are saved in the browser on the device, and the servers keep no copy of them. A draft left alone for eight days clears itself. The PDF and the editable Word file are both built on the device, so the finished resume is never uploaded anywhere in order to be made. When a step does need a model, it receives only what that step needs, over routes required to deny data collection and to retain nothing. The servers do keep a short list of records with no name, no contact field and no resume content in them, and those are kept for up to ninety days and then deleted.

The reason is who is holding the phone. Someone working on a library computer or a borrowed handset has a good reason not to want an account, and no particular reason to trust me with a document carrying their address on it.

The rest is unglamorous. One minimum tap size, set once as a rule. A live preview that is a second swipeable pane, not a panel beside a form. A wide screen that is still a narrow column, because the narrow column is the design and the desktop is the accommodation. It can be added to a home screen, and the shell keeps working with no signal.

It is measured against WCAG 2.1 AA. Automated checks run over the core screens in both themes every time the product changes, and a change that breaks one of them cannot ship. Manual screen reader reviews with TalkBack and VoiceOver are recorded and dated. The passes on physical handsets, a real iPhone and a real Android in somebody's hand, are still open.

The promises chose the stack

None of the engineering was settled in advance. Each promise above removed options until roughly one shape was left, and the shape is more interesting than the parts list.

No account and no copy of anyone's resume meant no database. Not a small one, none. The draft lives in the browser, so there is no schema, no migration, no backup, and no store of anyone's history to lose or leak. What runs on the server is a small Python app and a static bundle.

The person is on an inexpensive phone, so the interface carries no framework. The whole front end has one runtime dependency and it is the bundler. Everything else is plain modules, because a framework is weight the slowest connection pays for first.

Retaining nothing meant every outbound call goes over the standard library instead of a vendor kit, so the zero-retention instruction rides inside the request. A setting in somebody's dashboard can be switched off with no deploy and no failing test. A line in the request cannot. When an upstream does fail, each one has its own breaker and every step has a deterministic answer to fall back to, so a model outage costs polish and never the resume.

Never inventing a fact meant the occupation data is committed, not fetched live. A scheduled job rebuilds it from the public sources and opens a pull request only when an upstream dataset actually changed, and a person merges it, so a surprise revision cannot ship itself.

And because a promise that quietly stops working is worse than one never made, the gate is heavy. Structure, translation parity, imports and markup are checked before a single test runs, then the Python suites, the browser unit tests, and an end-to-end walk in two engines with automated accessibility checks in both themes. Staging redeploys on every merge and is verified as a genuinely deployed site, because cache headers, edge geography, and a deploy serving two builds at once are three things a local copy cannot fake. Production only ever takes a commit that passed.

Here is the whole of it, in the product's own words, including the parts that are not there.

CapabilityWhat it does for the personStatus
Situation-aware intakeTailors the questions and the resume format to the person's real situation.Shipped
Occupation groundingMatches a plainly typed job title to a real occupation and offers its true duties and skills to keep.Shipped
Broad or unmatched job titlesNarrow by field and role, browse the full list, or say none of them fit, and Rung grounds on nothing.Shipped
Skill helpProposes grounded skills to affirm, so nobody faces a blank list your skills line.Shipped
Live previewShows the real resume forming as they answer, by swiping between the answers and the document.Shipped
Polish reviewShows the finished lines back as readable text, with per-line correction and one make it stronger nudge.Shipped
Relevance checkGently flags a line that does not read like a real resume entry, and says why.Shipped
StylingColor, columns, font, spacing, and an optional photo where the market expects one, with a live preview.Shipped
Edit modePuts a pencil on every part of the finished document, so any line can be overruled.Shipped
Cover letterAn optional grounded cover letter tailored to a pasted job posting.Shipped
PDF and DOCX exportA real, applicant-tracking-friendly file in both formats, built on the device.Shipped
On-device privacyNo account and no server storage, and the draft survives a closed tab on the same phone.Shipped
Installable and offlineCan be added to a phone's home screen, and the shell keeps working with no signal.Shipped
Worldwide availabilityThe complete country-neutral builder everywhere, with reviewed United States and Mexico packs on top.Shipped
Read-aloudAny screen and question can be spoken aloud, for low literacy or low vision.Switched off
Voice conversation modeA hands-free loop that asks, listens, and moves on, for someone who cannot type at all.Switched off
Cross-device saveCarrying a draft to another device.Not yet
Accessibility evidenceAutomated WCAG 2.1 AA checks gate every change, with dated manual screen reader reviews published.Passes open

Read-aloud and voice conversation mode are the two I mind most, because they are finished. Speaking an answer instead of typing it, and having a screen read itself back, is close to the most useful accommodation for the people the last post was about, and they work. They are shipped switched off. A promise like that one ends up printed on a flyer that a caseworker reads aloud to somebody, and it stays off until it can be relied on.

And the thing that has not moved. I still cannot tell you how many people are standing at the bottom of that staircase. The firmest numbers I found were American, the need plainly is not, and two months of building has not given me a better figure than I started with. What has changed is that the tool now exists, which turns the question from whether to build it into how far it reaches. That second one I cannot answer by writing more code. If you know one person for whom an empty form is the wall, hand rung.guru to them.