Every screen in this app was produced by an agent reading a file I wrote.
Spotstars answers one question: what is this friend to me. Your friends sit on a printed star chart, sorted into six roles, and the app tells you who to stay close to today. I designed it, wrote it, built it, and I operate it. Six people use it daily on their own accounts. Sixteen days from an empty folder to version 11.7.
This is the real build, not a click-through. Every score below is computed live from the birth data of eight synthetic people.
The frame runs a copy of the production app with the database credentials removed, so it seeds a demo account in memory and makes no network calls at all. The maps, the roles, the scores, the readings and the copy pools are the shipped code. Try the three map views, open a friend, switch between Today, Month and Life.
Astrology apps are read alone, or one friend at a time. This one puts everyone on the same page and gives each person a job.
The people I built this for read their horoscope and then talk about it, with a partner, a sibling, a group chat, the person at the next desk. The existing apps do not support that conversation. They give you a paragraph about yourself, or a compatibility score against one other person, and the talking has to happen somewhere else.
So the unit of this product is not the reading. It is the map. Thirteen friends, six roles, one chart you can point at. Distance from the center is how good that person is for you today, which means the picture changes every morning and gives you something new to say.
The artifact is the rule that produced the screen. The screen is what falls out of it.
I measured the source when the case study was written. The astrology engine, the part that positions planets and computes a score, is the smallest thing in the project. Everything above it is language and rules: what the app is allowed to say, in what tone, in two languages, under which conditions.
That ratio is the whole argument. When an agent writes the code, the scarce thing stops being implementation and becomes specification. A screen I do not like is rarely a screen problem. It is a rule that was missing, or a rule that was wrong, and the fix has to land in the rule or it comes back on the next screen.
Working this way changed the question I ask in a review. It used to be what does this screen look like. Now it is which rule produced this screen, and is that rule right.
The design system is not one document. It is three, and they exist because three different things kept going wrong. Each one is a markdown file an agent reads before it touches anything.
119 lines. 43 rules across color, type, layout, components, do and don't, and hierarchy. 19 color tokens, 12 type steps, and an image-prompt paragraph so generated art comes back in the same world.
Without it: icons rendered as iOS colour emoji and broke the ivory palette on the first build.
Every user-facing sentence in both languages. Bans raw astrology vocabulary in body text. Enforces one test on every line: so what, for my day.
Without it: every reading resolved to some version of "reach out to them today".
Operating rules for the agent itself. Exact-string replacement only, never range deletion. Read and report, wait for confirmation, change, test, boot-check, commit.
Without it: a single line edit was one keystroke away from deleting 4,407 cities.
The third file is the one most design systems do not have, and it is the one that saved the project. A design system that a machine executes needs a section about what the machine is forbidden to do, not only what it should produce.
None of these were written in advance. Every one is the scar of something that went wrong in a build, got diagnosed, and got turned into a line an agent now reads before it starts.
The city database is a single enormous one-line object. An agent asked to remove some entries proposed a line deletion, which in that file means deleting all 4,407 cities.
The failure is silent. Tests pass, the app boots, and the country picker is empty three commits later.
The North Korea exclusion ran cleanly: 4,407 cities to 4,391, 248 countries to 247, verified by a test that guards those two counts.
The Life score on my own tab quietly reused the curve built for friend compatibility. Every result landed between 47 and 68. The screen looked fine. The numbers were wrong.
Given no rule, an agent reaches for the nearest existing thing that fits the shape. Reuse is its default, and reuse of a curve is invisible in a screenshot.
Six named curves, one per surface. Life on the Me tab now spans 55 to 100 with its centre in the seventies, like every other surface.
All thirteen friends rose and fell together on the same days. My own chart is the one input present in every pair, so it was driving all thirteen scores at once.
This is a design failure that only shows up in aggregate. On any single friend's screen the number is plausible. Only the map makes it visible.
My chart weighted at 0.3 against the friend's 1.0. Correlation between friends fell to zero, and the map now moves the way the concept promised.
Headlines were selected by which planet was strongest that day. Planets move slowly, so the same sentence held for four or five days and the app felt broken.
The obvious fix is to generate fresh text. That trades a copy problem for a quality problem and a cost. The real fix was structural.
Band-keyed pools with a running no-repeat cursor. 88 lines for the Me headline, 528 for friend headlines. Probability of a repeat inside 60 days is 6 percent, calculated rather than guessed.
The dark constellation set was generated separately from the light one. The poses came back different, so switching theme moved the artwork.
Two generations of the same prompt are two different drawings. Consistency across themes has to come from the pipeline, not from a better prompt.
One 4K sheet, twelve crops, then a colour transform for dark. 24 assets, 4.6 MB, pixel-identical across themes. It also corrected an older note in my own files: high-resolution sheets work fine, low-resolution ones do not.
I read the four apps people in this category actually use, and two of them changed a rule rather than confirming one.
The design system has a Known Gaps section. It is the section I trust most.
These are four defects visible in the screenshots above, taken from the live build on September 8. Three of them the rule files already predicted.
On the Roles map, two friends in the same sector render as one unreadable string. DESIGN.md lists cluster marks for crowded sectors under Known Gaps. The gap was documented before it became visible, and it is now visible.
The ring lines and the constellation artwork behind them sit at similar values in light mode, which competes with the friend names. Raised in an audit two weeks ago, still unresolved. The candidate fixes are lowering the artwork opacity in light only, or dropping it there entirely.
A friend screen shows a today score of 90 and area scores of 54, 41 and 38 on the same scroll. They are different scales, and nothing on the screen says so. A reader is right to ask which number to believe.
When one planet forms two aspects with the same meaning, the reading prints the identical clause twice in a row. The selection logic has no deduplication step. Reproducible, and small to fix.
The reason to build this was that people talk about their horoscope together. Right now every user still looks at their own map alone. Sharing is an invite link and nothing more. That is the largest gap between the concept and the build, and it is bigger than any of the four defects above.
The next version has to make the map a thing two people look at at once. Everything else on the roadmap, the account system, the paid tier, the ad placements, is downstream of that.
The part I will carry into any team is the working method. A design system written for a machine to execute, with a section on what the machine must not do, and a rule for every failure that has already happened once.
I can walk you through any rule in this system and the failure that wrote it.
The prototype above is the shipped code. The three markdown files and the commit history are available on request.
Ashley Kim · ashleykim1229@gmail.com
SPOT OM case study → · Platform Modernization → · Service Platform →