IOSProduct DesignSystems

I Built an App So My Lady Could Pass the CAPM

A native iOS app for my lady's CAPM prep, and the one rule it's built on: derive, don't ask.

I Built an App So My Lady Could Pass the CAPM

Derive, don't ask: what a one-user product teaches about onboarding, and about teaching itself

My lady Miranda is studying for the CAPM, the entry certification for project management. The prep options were the usual suspects: PDF dumps, question banks with interfaces from 2011, subscription sites that gate everything useful behind a paywall before showing you a single question. She needed a study plan, spaced repetition, and something that did not feel like punishment after a full workday.

I build software. So I built her the app.

Ascent went live on the App Store yesterday. It is a native SwiftUI app with 1,122 questions across the four CAPM domains, every one carrying a written explanation of why each answer is right and the others wrong, organized into 36 lessons, a placement quiz that never feels like a test, and a Boss exam scored against the real pass mark. It runs on Fundamental, the physics engine I built, which the entire interface is composited inside. This essay is not really a launch announcement, though. It is about a single design rule the app is built on, top to bottom, which I think most software gets backwards: derive, don't ask.

The rule: derive, don't ask

Open most apps in this category and the first thing you meet is a form. Name, email, goals, experience level, preferred study times, a marketing-consent checkbox. The product asks you to do data entry before it has demonstrated a single unit of value. Every question before value is a dropout risk, and the industry knows it, and the forms persist anyway, because asking is easier than deriving.

Ascent opens into the product. First screen: Pass the CAPM. Answer three questions, we'll build your study plan. No account, no email, no name. You are learning before you notice you were being onboarded.

Everything the app needs, it derives. Your goal comes from your exam date, because the date implies the pace. Your readiness comes from how you answer placement questions, not from a self-assessment dropdown, because people are bad at self-assessment and quiz behavior does not lie. Identity starts as an anonymous account created silently on first launch, so progress syncs from minute one; if you later want it on a second device, Sign in with Apple links the account you already have. The app never asks for what it can calculate.

There is a corollary that matters just as much: no silent wrong defaults. Deriving means the app makes assumptions, and an assumption the user cannot see is a bug waiting to embarrass you. If the default exam countdown says sixty days and her exam is next week, the daily plan is wrong in a way that compounds. So setting the exam date is not a buried default you have to catch. It is the last step of onboarding, pre-filled with a guess and put directly in front of you to confirm or change, before you ever reach the app.

The same restraint governs permissions. Ascent does not ask to send notifications on first launch, when it has done nothing for you and the ask is pure imposition. It asks after you finish your first lesson, once it has actually earned a place on your lock screen. Permission is a thing you grant to software that has already been useful, not a toll you pay to try it.

Ask only what you cannot derive. Surface everything you assumed. Earn everything you request. That is the whole onboarding.

Why a user of one makes the design honest

Building for one specific person is the best design constraint I know. Miranda is not a persona or an aggregate. She studies after work, tired, on a phone. Every friction I might have shrugged off as acceptable, I watched cost her real minutes and real patience. A signup form would not have been a conversion-funnel abstraction; it would have been my partner, on the couch, giving up for the night.

The same honesty runs straight through to how the app teaches, because the derive-don't-ask rule is not only about onboarding. Asking a tired person to configure their study preferences is offloading the product's job onto the user. The exam date, the placement results, the entire answer history: the app has everything it needs to do its own job. So it does.

How it teaches: a memory model, not a syllabus

It starts by finding out where Miranda actually is. Onboarding asks how ready she feels, a single confidence slider, and then, with the particle field deliberately switched off so nothing competes for her attention, gives her three real questions. The reveal puts the two numbers side by side: how ready you feel, how ready you are. The felt number is a foil; the study plan runs on the measured one. It is the whole rule at the moment of first contact. The app would rather show you the gap than take your word for it. (That the field goes dark for the quiz is the same discipline as everywhere else: the ambience gets out of the way in exactly the moment focus matters.)

Under the lessons is a spaced-repetition engine. Every question is a flashcard with a small memory model attached: an interval, an ease factor, a repetition count, a lapse count, a due date. Answer it correctly and the interval stretches, one day, then three, then multiplied out by the card's ease each time, and the card drifts toward the back of the deck. Miss it and the interval collapses to a single day, the lapse count ticks up, the ease drops, and the card jumps the queue. This is the SM-2 algorithm that every serious flashcard app is built on, tuned so that a question seen three clean times counts as mastered and stops taking your time.

The daily route is not a fixed syllabus. It is computed, every session, from that memory model. A priority score ranks all 1,122 questions at once: a question you have never seen scores high, a question that is overdue scores higher, one you have lapsed on repeatedly higher still. A question you have answered right three times, comfortably, on schedule, scores negative and drops away. The plan is the top of that ranking, capped so no single topic dominates, then shuffled so it never feels mechanical. What you drill tomorrow is a function of what you got wrong today.

Readiness works the same way: derived, never self-reported. The ring that fills as you study is a four-factor score computed per domain. Your accuracy, how much of the domain you have actually covered, how much you have retained rather than just seen once, and how broadly your strength spreads across the sub-topics. Those four are weighted by the real exam's domain blueprint and blended into one number, with a deliberate handoff: early on, before there is enough live data, the ring leans on your placement quiz; as coverage grows past halfway, it leans entirely on your behavior. The number is meaningful on day one and honest by the end.

And it finds your weak spots three different ways, because "weak" has more than one shape. It knows your weakest domain. It sorts every question into one of about sixty topic areas, earned value, critical path, risk response, the agile ceremonies, OPAs and EEFs, and knows the weakest of those. And it tracks an "Achilles' heel": the question formats you keep missing (scenario questions, sequencing) and the specific repeat-offender questions you have gotten wrong two or more times. A comfortable plan that reviews what you already know feels productive and quietly fails you on exam day. This one refuses to; it is built to be honest about what she does not know, because that is the only thing worth her evening.

None of this feels like a spreadsheet, because the questions do not all wear the same clothes. There are six formats: true/false, multiple choice, matching, hotspot, scenario, and sequencing. The curriculum is a path you climb rather than a list you scroll, with the whole four-domain outline laid out as a route and your current position glowing on it. Woven through it are eight short branching conversations, a sponsor named Priya asking what you need from her before the project spends a dollar, where the "question" is a decision and the wrong choice teaches by consequence. There is a timed Boss exam scored against the real pass mark, a flashcard deck for the pure-recall material, and a one-tap formula sheet for exam-day math. Same memory model underneath all of it; different surfaces, because a tired person needs the format to change even when the science does not.

One detail I am quietly proud of: your memory of a question is keyed to a stable, content-addressed ID, not to the question's text. Which means I can fix a typo, reorder the curriculum, or add a hundred questions, and nobody's months of spaced-repetition history get orphaned. The structure protects the guarantee so the product never has to apologize.

The interface is the physics: how Ascent relates to Fundamental

Here is the part that is not like other study apps. The entire interface does not sit on top of a background. It is composited inside a running physics simulation.

Fundamental is a particle engine I wrote. In Ascent, one field spans the whole app, and every screen lives within it. The particles are not a looping video or a static gradient; they are simulated, Metal-batched, one draw call each, drifting on a wave field behind everything you touch.

And everything you touch is a body in that field. A button does not rest on the particles; it pushes them. Interactive elements register as deflectors that make particles swirl past. A hero node becomes a vortex that pulls them into slow orbit. A correct answer throws a burst. The motion you see around the interface is the interface's own physics reacting to itself.

Then the field reads your progress. Its density rises with your exam readiness and climbs a little more with your streak, so when Miranda is deep in a domain she has nearly mastered, the room around the questions is dense and alive, and on a rusty day it is quieter, telling her something before the numbers do. Its palette shifts to the color of whatever domain she is currently working. Break a streak and the whole field contracts to near-black for a couple of seconds before it recovers: a small, wordless acknowledgment that you lost something, with no modal and no badge to shame you about it. The ambience is not decoration. It is a readout of your learning state, rendered in particles.

The discipline underneath it is the same rule again. There are hard budgets: a strict cap on particle density, one draw call per particle, a frame budget the ambience is never allowed to exceed. A beautiful field that costs you a dropped frame on a tap would fail the same honesty test as a comfortable study plan. Ambience that apologizes for itself is worse than none. So the simulation is built to be invisible in exactly the moments it would otherwise get in the way.

The look: one job per color

The aesthetic has a name in the codebase, Neon Arcade, and a rule sheet to match: a dark, near-black space, a handful of saturated neon accents, type set entirely in SF Rounded so the interface reads as friendly rather than clinical. But the look is not really about the colors. It is about giving each color exactly one job and never letting it moonlight.

Green means correct: a right answer, a mastered topic, a readiness ring that has crossed into safe territory. Cyan is you: your gem count, your place in the weekly league, the "continue" that carries you forward. Pink is the live challenge: the node you are on right now, the exam you are about to submit, the CAPM itself. Amber is anything in progress or earned: a partial readiness, a flagged question, the streak counter. And red means one thing only. Red is wrong. It appears on an incorrect answer and a failing score and nowhere else: never as a decoration, never as an accent because a screen needed some warmth. In a lot of apps color is mood lighting. Here it is vocabulary, and the most important word in it is the one the app refuses to say unless it means it.

That refusal is the whole design philosophy compressed into a swatch. The interface never cries wolf. When the field collapses to black, you broke a streak. When something turns red, you got it wrong. Nothing on screen is theater; every signal is load-bearing. It is the same honesty as the study plan and the same restraint as the onboarding, expressed in pigment instead of logic. Which is also why the exact same palette, down to the hex values, drives the iOS app, the Android build, and the website. One vocabulary, spoken everywhere, so the app means the same thing no matter where you meet it.

The game layer, pointed the right way

A study app with streaks and gems and a daily quest should make you suspicious. Those are precisely the mechanics engagement-farming apps use to manufacture compulsion, and I spent the whole essay so far claiming this one is built on restraint. So it is worth being exact about what they are pointed at.

Miranda earns gems by studying and XP by finishing lessons; a streak counts the days she actually shows up. The one thing gems buy that matters is a streak freeze: you spend what you earned to forgive a single missed day. That is loss aversion turned for the user instead of against them. The mechanic exists to soften the punishment of a bad day, not to weaponize the fear of one into a reason you can't put the phone down. The daily quest rewards completing study, never merely opening the app. There is no infinite feed, no leaderboard tuned to keep you scrolling, and the single notification is a streak nudge you opted into after your first lesson, not a hook cast at a weak moment.

And there is nothing to milk. The full unlock is one purchase, once. No subscription, no expiry, and the first domain stays free. You can buy a top-up of gems; you never have to, and there is no second charge waiting for you. I will be honest that a gem economy with an optional paid top-up is the one place a reader could reasonably raise an eyebrow, so here is the test I actually held every mechanic to: does it serve Miranda's deadline, or does it serve a retention metric? Streaks that protect her momentum, a plan that targets her weak spots, an unlock she buys once and owns: those serve the deadline. Anything that only served the metric did not get built. A study app's honesty is measured on exam day, not in time-on-device, and the whole thing is tuned to the first number.

The stack, briefly

For the builders: native SwiftUI, with the whole interface rendered inside a Fundamental field. Metal-batched particles, palette-first, on a strict density and frame budget so the physics never costs the interaction. Content ships from an API with an on-device cache, so a full study session works with no signal at all: the train, the basement, the waiting room, wherever the evening actually happens. Progress lives in a store that merges field by field, tolerant of missing keys, so no sync race and no schema change ever loses a completed lesson. Path progress and spaced-repetition history are both keyed to content-addressed IDs, which is what lets me reorder or expand the 1,122-question curriculum without wiping anyone's record. Questions come in six formats, true/false through sequencing, and each is worth XP scaled to its cognitive demand, from recall up through application. The same Fundamental engine already runs on Android; the app around it is underway.

The whole thing is built to one rule: the structure enforces the guarantee, so the product does not have to apologize.

The kicker

Miranda's exam is coming up. The app exists because she needed it, and it shipped because a user of one is still a user, with a real deadline, which is more grounding than most product roadmaps ever get.

If someone in your life is staring down the CAPM, it is on the App Store: Ascent CAPM Prep. Free to start, no account required. That last part is the whole philosophy in four words.


Related: Distance from Gray — the doctrine underneath: derive-don't-ask is gray reduction on the input side, measuring intent instead of interrogating for it. Site: ascent.guide.