We Built a Horoscope Report Engine in Half a Day

Not a prototype. Not a proof of concept. A production-grade, 105-test-assertion, visually polished, standalone HTML horoscope report generator β€” built, tested, and shipped in a single session.

What we built: A Western astrology engine that takes a name and birth date, computes the sun sign, personality profile, and Jupiter transit outlook, and renders a self-contained HTML report with a light/dark theme toggle, sidebar navigation, scroll progress, an interactive I-Ching oracle, and Stoic philosophical closing quotes. No dependencies. No install. No account. Just open the file.

How we built it: The same way we built the BaZi (Chinese astrology) engine before it β€” a proven pipeline architecture: compute β†’ shape β†’ render. We wrote a design spec first (v0.10B), peer-reviewed it twice, caught four structural defects before writing a single line of code, then transcribed the spec into code block by block. Every function is pure. Every test is deterministic. Every bug was shallow.

Why it matters: The pipeline pattern β€” spec first, template second, domain third β€” is now proven across two completely different astrological domains. BaZi is a Chinese metaphysics system based on heavenly stems and earthly branches. Western astrology is a zodiac-based system built on planetary positions and aspects. Same architecture. Same test harness. Same rendering pipeline. Different constants.

What’s next: The feature gap analysis is honest β€” we’re at sun sign level while the market expects full natal charts (all 10 planets, houses, aspects, transits, progressions). The architecture scales there. The question is whether we want to.

The real lesson: When the template is right, adding a new domain is mostly transcription. The hard work happened in the template β€” the DotDict infrastructure, the compute/shape/render separation, the schema scaffolding, the test harness. Once that existed, the western build was mechanical. Phase 2 rigor made Phase 3 boring. That’s the point.


Session Log β€” Western Horoscope Build

Time Block Action Result
0:00 Spec Wrote Design Spec v0.10B from scratch β€” 8 sections Single-pass, clean
0:15 Spec Peer Review 1 β€” caught placeholder gap in Β§2.7, missing cosmic_now Fixed
0:25 Spec Peer Review 2 β€” caught Jupiter index error (2024=Aries, not 2023), rejected unused table Fixed
0:35 Code Skeleton β€” copied from bazi_template, stripped domain, left infra 106 assertions passing
0:45 Code Block 1 β€” Constants (SIGN_DATES, SIGN_DATA, ELEMENT_PROFILE, QUALITY_PROFILE, ASPECT_TABLE, RULER_INFLUENCE) 8 tests
0:55 Code Block 2 β€” Compute Tier 2 (derive_sun_sign, derive_sign_profile, derive_jupiter_aspect) 21 tests
1:05 Code Block 3 β€” Compute Tier 1 (compute_western) 10 tests
1:15 Code Block 4 β€” Shape (shape_sign_profile, shape_running_year) 14 tests
1:25 Code Block 5 β€” Render (render_sign_profile_section, render_running_year_section) 7 tests
1:35 Code Blocks 6+7 β€” Registry wiring + variant tests 106/106 total
1:45 Debug Ran --debug β€” inspected out.json + out.html Caught oracle bug, archetype placeholder
2:00 Polish CSS western section β€” all .sign-, .archetype-, .nature-, .traits-, .year-* classes Added ~60 lines
2:10 Polish Closing refactor β€” Chinese quotes β†’ Stoic (Marcus Aurelius + Seneca) quote_first/quote_second pattern
2:20 Polish Oracle removal β€” removed from western pipeline, kept interactive Cast Clean
2:30 Polish Archetype body narratives β€” all 12 signs Replaced β€œβ€¦β€ placeholder
2:40 Polish Fixed quote_second CSS class bug (underscore vs hyphen) One character
2:45 Verify --test 105/105, --debug cross-check, folder output All clean

Total: ~3 hours including spec, reviews, code, and polish.

Bugs caught pre-code (during spec): 4 Bugs caught post-code (during debug): 4 Structural rework needed: 0