astral-transit-calendar

/home/avalon/.hermes/skills/astrology/astral-transit-calendar/SKILL.md · raw

Astral Transit Calendar

Overview

This skill is the local Hermes workflow for turning Alex's transit-list-demo code into reusable transit context and calendar feeds.

It supports two complementary use cases:

  1. Global transits — exact planetary aspects/ingresses in the sky, independent of a natal chart.
  2. Alex transits — exact transiting aspects to Alex's natal planetary positions.

The canonical local store is:

~/.hermes/astral-transits/
├── astral-transits.js                  # generator script
├── profiles/alex.json                  # Alex profile/natal UTC metadata
├── events/*.json                       # structured events for Hermes context/RAG
├── calendars/*.ics                     # Apple/Google import/subscription files
└── reports/*.md                        # mobile-readable summaries

When to Use

Use this skill when Alex asks for:

Do not invent transit times. Use transit-list-demo via the generator or API.

Source Service / Code

Local code:

/home/avalon/apps/transit-list-demo

Public API:

https://transit-list-demo.apps.poofc.com

Useful existing API endpoints:

GET /api/health
GET /api/transits/current
GET /api/time/resolve?date=YYYY-MM-DD&time=HH:mm[:ss]&location=LOCATION
GET /api/chart?date=YYYY-MM-DD&time=HH:mm[:ss]&location=LOCATION
GET /api/chart?utc=day/month/year/hour/minute/second&coordinates=LAT%20LON

Important implementation finding: server.js currently exposes current/chart endpoints, but not a dedicated HTTP scan endpoint for date-range transit calendars. Date-range scanning exists in the CLI / Program.scan(start, stop, natal) path. Use the local generator for calendars until a /api/transits/scan endpoint is added.

Alex Profile

Confirmed Alex profile file:

~/.hermes/astral-transits/profiles/alex.json

Confirmed birth data:

Date: 1985-09-26
Local time: 07:14:00
Location: London, UK
Timezone: Europe/London
UTC: 1985-09-26T06:14:00.000Z
transit-list-demo natalUtc: 26/9/1985/6/14/0
Coordinates: 51.5072178, -0.1275862

Source: Alex confirmed this in Telegram on 2026-05-13. UTC was resolved through transit-list-demo /api/time/resolve.

Generator Commands

Generate global + Alex transit datasets and .ics feeds for the rest of 2026:

~/.hermes/astral-transits/astral-transits.js --kind both --start 2026-05-13 --end 2027-01-01

Generate a full calendar year:

~/.hermes/astral-transits/astral-transits.js --kind both --year 2026

Generate global-only:

~/.hermes/astral-transits/astral-transits.js --kind global --start 2026-06-01 --end 2026-07-01

Generate Alex-only:

~/.hermes/astral-transits/astral-transits.js --kind alex --start 2026-06-01 --end 2026-07-01

Include Moon if Alex explicitly wants a high-volume calendar or a high-frequency timing dataset for strategy research/trading experiments:

~/.hermes/astral-transits/astral-transits.js --kind both --year 2026 --include-moon

For crypto/market-timing research, the Moon should usually be treated as an execution-timing layer rather than a background calendar layer: use Moon ingresses, degree pulses, applying/separating aspects, and translations as frequent testable triggers, with Sun/Mercury/Venus as setup windows and Mars/Saturn/Jupiter as regime filters.

Default planet set excludes Moon for normal calendar signal/noise and excludes South Node because it is always opposite True North Node and creates duplicate node-opposition spam:

Sun, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, True North Node

Output Files

The generator writes:

~/.hermes/astral-transits/events/global-START_to_END.json
~/.hermes/astral-transits/events/alex-START_to_END.json
~/.hermes/astral-transits/events/combined-START_to_END.json
~/.hermes/astral-transits/events/current-transits.json
~/.hermes/astral-transits/calendars/global-START_to_END.ics
~/.hermes/astral-transits/calendars/alex-START_to_END.ics
~/.hermes/astral-transits/reports/report-START_to_END.md

JSON is the canonical Hermes context store. ICS is a calendar interchange/export artifact.

Event Schema

Each JSON event has this shape:

{
  "id": "global-20260602T224842Z-Sun-Sextile-Saturn",
  "kind": "global",
  "profileId": null,
  "title": "Sun Sextile Saturn",
  "summary": "Global transit: Sun Sextile Saturn",
  "startUtc": "2026-06-02T22:48:42.000Z",
  "endUtc": "2026-06-02T22:48:42.000Z",
  "allDay": false,
  "eventType": "aspect",
  "aspect": "Sextile",
  "orb": "exact",
  "planet1": "Sun",
  "planet2": "Saturn",
  "position1": { "degree": 12, "minute": 24, "second": 25, "sign": "Gemini", "longitude": 72.407 },
  "position2": { "degree": 12, "minute": 24, "second": 25, "sign": "Aries", "longitude": 12.407 },
  "source": "transit-list-demo",
  "raw": { }
}

Ingress events use:

{
  "eventType": "ingress",
  "planet1": "Mercury",
  "planet2": "Cancer",
  "title": "Mercury enters Cancer"
}

Calendar Sync Pattern

Apple Calendar / Google Calendar can import .ics files directly. For ongoing sync, expose ~/.hermes/astral-transits/calendars/ via a stable HTTPS path, then subscribe to those URLs from calendar clients.

Recommended future hosting path if needed:

https://astral-transits.apps.poofc.com/calendars/global-current.ics
https://astral-transits.apps.poofc.com/calendars/alex-current.ics

For now, deliver or copy the .ics files manually from:

~/.hermes/astral-transits/calendars/

Tenant KB persistence (Phase 4)

After every generator run, mirror the outputs into astral-tenant-kb so reading skills can pick them up by slug + range.

KB=~/.hermes/skills/astrology/astral-tenant-kb/scripts/kb.py
RANGE=2026-05-13_to_2027-01-01

# global window
python3 $KB save_global_transits $RANGE --json ~/.hermes/astral-transits/events/global-${RANGE}.json

# per-person window
python3 $KB save_transit_profile alex $RANGE --json ~/.hermes/astral-transits/events/alex-${RANGE}.json
python3 $KB save_transit_calendar alex $RANGE --ics  ~/.hermes/astral-transits/calendars/alex-${RANGE}.ics

Hard rules: - Only mirror after the existing transit-first label normalization passes verification (see "Reading Transits into a Hermes Reply" step 4–6). - range_id format: YYYY-MM-DD_to_YYYY-MM-DD — used as the filename suffix. - The original ~/.hermes/astral-transits/ tree remains the working set; the KB mirror is the per-person canonical store that reading skills consult.

Reading Transits into a Hermes Reply

For a concise mobile response:

If Alex asks for transits as part of another person's reading package, interpret current transits to that subject's natal chart, not Alex's transits. Use the subject's saved natal chart JSON when available, fetch current transits with curl -sS https://transit-list-demo.apps.poofc.com/api/transits/current, then compute major aspects from transiting planets to natal planets/angles with sensible orbs (rough defaults: Moon 1.5°, Mercury/Venus/Mars/Nodes 2°, Sun 2.5°, Jupiter/Saturn 3°, Uranus/Neptune/Pluto 2.5°). Lead with exact/high-impact overlays and synthesize them back into the natal + HD themes.

  1. Read the relevant report first: text ~/.hermes/astral-transits/reports/report-START_to_END.md
  2. If a specific date is requested, filter the JSON events by startUtc date.
  3. Separate kind=global from kind=alex.
  4. For kind=alex aspect events, the generator must normalize labels and fields to transiting body → natal body. The raw upstream transit-list-demo scan may emit natal body first because it searches p1 = natal longitude, p2 = transiting planet; keep that raw object only under raw for audit, never as the user-facing title/summary/ICS label.
  5. Verify Alex aspect events expose body1Role: "transit", body2Role: "natal", transitPlanet, and natalPlanet before interpreting or importing into downstream knowledge bases. Do not rely on a visually corrected title alone; validate the role fields (planet1 === transitPlanet, planet2 === natalPlanet) so stale natal-first copies fail fast.
  6. If a KB/prototype import is involved, regenerate from the canonical ~/.hermes/astral-transits/events/*.json after normalization and then search both the source store and KB for stale labels such as Saturn Opposition Mercury.
  7. Mention UTC unless converting for Alex's local Pacific time.
  8. Interpret using Alex's astrology style if interpretation is requested; otherwise report exact event facts.

Downstream: transit-derived UX captions

Astral Hermes loading states (provisioning spinner, chat stalls, etc.) use a filler-caption layer fed by the daily transit pipeline. The pipeline emits a small captions array alongside the JSON events, and the web app serves it from /api/daily-captions. See chat-interface-development SKILL.md → "Filler caption layer" for the consuming UI shape.

Caption generation rules (Alex called the first-pass invented filler "dumb and cheesy" — these are hard rules):

Pipeline shape:

  1. VPS cron (hourly, for Moon-degree + planetary-hour drift) → writes /data/hermes/astral-daily/global-<timestamp>.json with { generatedAt, transits: {...}, captions: [...] }.
  2. Astral Hermes web serves GET /api/daily-captions → global captions.
  3. Per-tenant cron at provisioning time (daily) → writes <tenant_kb>/transits/daily/<date>.json with natal-overlay captions.
  4. Astral Hermes web serves GET /api/daily-captions?tenant=<id> → tenant-specific if available, else falls back to global.

Caption template examples (templatically derived from JSON, not hand-written one-shots):

Generator script lives at astral-hermes-platform/scripts/daily-transits.mjs (planned). It should accept --natal <utc-string> --coordinates <lat lon> to emit per-tenant overlays; without those args, it emits global-only.

Verification Checklist

References

Common Pitfalls

  1. Using /api/transits/current for a date range. That endpoint only gives current positions. Use the local generator/CLI scan.
  2. Forgetting UTC day-first format. Transit-list-demo dates are day/month/year/hour/minute/second in UTC.
  3. Including Moon or South Node by default. Moon creates a noisy high-volume calendar. South Node is always opposite True North Node and can produce duplicate node-opposition spam. Only include them when Alex explicitly wants that layer and understands the volume.
  4. Using stale Alex birth data. Alex's confirmed chart is 1985-09-26 07:14 London, UK → 26/9/1985/6/14/0 UTC date string. Do not use recovered/demo SVG values or any unconfirmed Alex birth data.
  5. Calendar subscription vs import. A file import is one-time. True sync requires serving the .ics at a stable URL and subscribing to it.