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