I Automated Astrology in Six Languages. I Don't Believe a Word of It.
I don’t believe in astrology. I built a machine that manufactures it in six languages, every night, forever — and the disbelief is the least interesting thing about that sentence. It’s just what let me use astrology as a payload: an evergreen, computable, relentless thing to feed a content machine while I built the part I actually cared about. And that part handed me a lesson that has nothing to do with horoscopes and has held up everywhere since. You can fully automate the production of content. The moment you try to localize it, meaning and register and cultural authority step forward and politely refuse to be a pipeline stage.
The itch came from watching people around me check a daily horoscope video the way you check the weather: more than once a day, on repeat, for comfort. You don’t have to believe content to see the craft in it, and as a payload for a content machine, astrology is close to perfect. It’s daily and evergreen, so you’re forced to genuinely automate instead of hand-craft. It’s templated — twelve signs on a fixed skeleton. It’s grounded in computable data — real planetary positions, not opinion, so the input is deterministic. And the same skeleton exists in every culture, which makes it the ideal thing to fan a localization engine out across. I wasn’t building a horoscope channel. I was building a localization engine, and I needed something relentless to feed it.
The machine
The pipeline is prosaic and end-to-end. Compute the astronomical data deterministically — a JavaScript astronomy library, then an adaptation layer that maps it into the Vedic system. Hand that structured context to a model, which writes each sign’s prediction as JSON. Turn the prediction into a spoken script. Generate natively in a couple of languages and translate out to the rest. Synthesize a voice per language. Assemble a faceless video with FFmpeg — background, text, audio, captions. Publish on a schedule. A cron row drops jobs into a queue; a worker grinds each stage with checkpoints and retries. Six languages, twelve signs, five or six minutes a night, fifteen or twenty dollars a month. No human anywhere in the loop.
That part worked almost immediately. The part that humbled me was the word I’d used most casually: localize.
Localization is not translation
I assumed the pipeline was language-agnostic. Swap the voice, point it at a new market, done — the machinery doesn’t care what language it’s speaking. That assumption was wrong in a way no test could have caught.
The format — a faceless, computer-voiced, here-is-your-day authority — worked in the culture I built it for, where a disembodied voice reading out predictions feels legitimate. Ported to an English-speaking audience, the identical output — same structure, same quality, same everything — reads as spam. Those viewers want a face, a personality, a joke; astrology there is identity-play, not received authority. Same machine, opposite reception, and nothing in the code base could have told me, because the failure wasn’t in the code. Translation is the easy ten percent. The register — who is allowed to say this, in what voice, with what claim to authority — is the ninety, and it’s the tutorial-versus-the-real-thing gap again, in a place no code review could reach.
Once I stopped confusing the two, the actual shape of “localization” showed up, and almost none of it was translation:
- Naturalness is a rules problem, per language. The generation prompts slowly accreted forbidden-phrase lists, tone mappings, opening-line rotations, and language-purity rules — no English “subscribe” sneaking into a Tamil sign-off — one hard-won constraint at a time. Machine translation gives you none of that.
- Pivot language matters. Translating directly between two linguistically distant languages reads worse than routing through a third. “Just translate it” hides a routing decision.
- The voice is the ceiling. TTS goes robotic in some languages, mangles names, and falls apart on code-switching — the same naturalness wall I hit teaching pronunciation. You can automate everything upstream of the voice, and the voice will still be the visible seam that says a machine made this.
The engine was the point
The piece I’m proudest of is the one that outlived the experiment. Voice selection stopped being a list and became an architecture: a linguistic spine — language, then dialect, then accent — crossed with orthogonal facets like archetype, voice model, and register, composed at runtime. With one rule I’d keep in any system that previews generated media: personas can be compositional, but the audio samples get materialized once and locked, or every preview click is a fresh TTS bill.
And when I later automated a completely different content channel, the accounting was blunt: seventy percent of the machine already existed — the script generation, the per-language voice, the video assembly, the publishing. The horoscopes were disposable, and I always knew they were. The spine — compute, generate, localize, voice, assemble, publish — was the thing I was actually building. The payload was just the excuse relentless enough to make me finish it.
What a skeptic sees
Here’s what building it showed me. The prediction prompt slowly turned into a psychology engine: statements vague enough to feel personal, an undercurrent of hope even in a bad forecast, the Barnum effect written down as instructions. A believer wouldn’t design that on purpose. A skeptic can’t design anything else, because the mechanism is all he sees.
Which clarified something about automated content generally. This is content-as-a-system, not content-as-meaning. The machine optimizes cadence, structure, and variety flawlessly, and it has no stake whatsoever in whether any single prediction is true — because there’s no truth for it to be true to. You can make it endless. You cannot make it mean anything. Horoscopes are the honest test case precisely because meaning was never the deliverable, and the machine performs exactly as well as it would on content where meaning is the point — which should worry you.
The reminder that no one was minding the store came from two bugs I found much too late. A scoring rule that could never fire, because the astronomy layer never computed the flag it depended on — a rule waiting forever on an input that never arrived. And a retrograde check that got the one day a planet actually turned exactly wrong, because it compared today to tomorrow instead of straddling the moment. Both ran live, confidently, for who knows how long, because automation removes the editor who’d have caught them. A silent wrong answer is the expensive kind, and I’d built six languages of no one watching.
I still don’t believe a word of it — but I believe in the engine, and I believe the warning it left me with. We can now produce content endlessly, in any language, about anything, with nobody in the loop to check whether it’s true. Astrology was the honest test case only because it was never supposed to mean anything in the first place. Most of what this machinery gets pointed at won’t have that excuse.