--- name: hd-prism-chart-data-workflows description: "Use when pulling existing HD Prism charts/readings from the app database or generating new charts from local birth data using the correct timezone-to-UTC workflow." version: 1.0.0 author: Hermes Agent license: MIT metadata: hermes: tags: [hd-prism, human-design, sqlite, charts, readings, timezone, utc] related_skills: [hd-prism-app, astrology-location-time-utc] --- # HD Prism Chart Data Workflows ## Overview Use this skill to do two related jobs on Alex's VPS: 1. Pull existing Human Design chart data and chart readings from the live HD Prism database. 2. Generate a new chart from local birth data, converting the birth moment to the correct UTC instant before calling the HD Prism chart engine. This skill is for direct operational work on the deployed app data, not vague theory. Prefer reading the database and app source first, then using the same internal app helpers the production app uses. ## When to Use Use when: - Alex asks to inspect charts already saved in HD Prism. - Alex wants a reading or chart JSON pulled from the DB for an existing user/chart. - Alex wants a new chart generated from birth date, birth time, and location. - You need to confirm how a stored chart was calculated. - You need to backfill or inspect Human Design metadata like type, profile, authority, channels, gates, or environment. Do not use for: - General astrology-only charts that live outside HD Prism. - UI-only changes with no database or chart-generation work. ## Paths and live services - Repo root: `/home/avalon/apps/hd-prism` - API app: `/home/avalon/apps/hd-prism/apps/api` - Client app: `/home/avalon/apps/hd-prism/apps/hdprism` - Live API DB (usual active DB): `/home/avalon/apps/hd-prism/apps/api/descriptions.sqlite` - PM2 API process: `hd-prism-api` - PM2 client process: `hd-prism-client` - Public domain: `https://hdprism.apps.poofc.com` ## Important source files Read these first: - `apps/api/src/descriptions/descriptionDb.ts` - `apps/api/src/models/bodygraph.ts` - `apps/api/src/generate-pdf-report.ts` - `apps/api/src/interpretation/chartFingerprint.ts` - `apps/api/src/routes/charts.ts` - `apps/api/src/humanDesignEnvironment.ts` ## Part 1: Pull existing charts/readings from the DB ### Full reading generation from a saved chart When Alex asks for someone’s “HD reading” and the chart already exists in HD Prism, don’t regenerate the chart from birth data. Pull the saved chart JSON by name/id/fingerprint, then call the real reading generator with that bodygraph. Workflow: 1. Search saved charts, including likely typos: ```bash cd /home/avalon/apps/hd-prism/apps/api sqlite3 -json descriptions.sqlite " SELECT id,user_id,name,created_at,updated_at,chart_fingerprint FROM saved_charts WHERE lower(name) LIKE '%jack%' OR lower(name) LIKE '%jax%' ORDER BY datetime(updated_at) DESC LIMIT 20;" ``` 2. Check whether a full reading already exists: ```bash sqlite3 -json descriptions.sqlite " SELECT id,chart_fingerprint,engine_id,model,prompt_version,status,sections_total,sections_completed,created_at,updated_at,error_message FROM readings WHERE chart_fingerprint='' ORDER BY datetime(created_at) DESC;" ``` 3. If none exists, extract the saved `chart_json` and call the streaming generator locally. This uses the same full LLM reading route as the app and persists to `readings` / `reading_sections`: ```bash python3 - <<'PY' import json, sqlite3, pathlib conn = sqlite3.connect('/home/avalon/apps/hd-prism/apps/api/descriptions.sqlite') row = conn.execute('SELECT chart_json FROM saved_charts WHERE id=?', ('',)).fetchone() pathlib.Path('/tmp/hd_reading_payload.json').write_text(json.dumps({ 'bodygraph': json.loads(row[0]), 'regenerate': False, })) PY cd /home/avalon/apps/hd-prism/apps/api curl -N -sS -X POST 'http://127.0.0.1:3005/api/readings/generate' \ -H 'Content-Type: application/json' \ --data-binary @/tmp/hd_reading_payload.json \ | tee /tmp/hd_reading_sse.log ``` 4. Verify completion in SQLite and export if needed: ```bash sqlite3 -json descriptions.sqlite " SELECT id,status,sections_total,sections_completed,created_at,updated_at,error_message FROM readings WHERE chart_fingerprint='' ORDER BY datetime(created_at) DESC LIMIT 1;" ``` Important distinction: - `POST /api/tenant/report` is fast and deterministic; it returns the assembled report/fact-pack structure without LLM prose. - `POST /api/readings/generate` is the full HD Prism reading generator; it uses OpenRouter, persists sections/overviews, and can take around 1–2 minutes after parallelization depending on model/API latency. ### Discover the schema Start by checking the table definitions: ```bash cd /home/avalon/apps/hd-prism/apps/api sqlite3 descriptions.sqlite ".tables" sqlite3 descriptions.sqlite ".schema saved_charts" sqlite3 descriptions.sqlite ".schema generated_readings" ``` If needed, also inspect related tables such as users or comparisons. ### Inspect saved charts Example query: ```bash cd /home/avalon/apps/hd-prism/apps/api sqlite3 -json descriptions.sqlite ' SELECT id, user_id, name, created_at, updated_at, chart_json FROM saved_charts ORDER BY datetime(created_at) DESC LIMIT 5; ' ``` Notes: - `chart_json` is the main payload. - It often contains type, profile, authority, definition, activations, gates, channels, incarnation cross, variable, and sometimes environment. - For older rows, environment may not be stored explicitly. If missing, derive it from `chart_json.activations.Design.SouthNode` using the app helper logic. ### Pull readings tied to a chart First inspect schema/foreign keys, then query by chart id or fingerprint depending on the current schema: ```bash cd /home/avalon/apps/hd-prism/apps/api sqlite3 -json descriptions.sqlite ' SELECT * FROM generated_readings ORDER BY datetime(created_at) DESC LIMIT 5; ' ``` If chart linkage is not obvious, inspect `descriptionDb.ts` for the exact lookup path used by the app. ### Safe extraction workflow 1. Read schema first. 2. Query a small result set. 3. Parse `chart_json` before making claims. 4. If the user asks for one chart, filter by `id`, `user_id`, or chart fingerprint. 5. If you need reading text, return the exact DB field, not a paraphrase, unless asked to summarize. ## Part 2: Generate a new HD Prism chart correctly ### Core rule Do **not** treat the user's local civil time as UTC. You must: 1. Resolve the birth timezone from the location or use the supplied IANA timezone. 2. Convert the local birth date/time into UTC. 3. Pass that UTC instant into the HD Prism chart generator. ### Production pattern HD Prism follows this pattern in `generate-pdf-report.ts`: - geocode birth location - resolve timezone for the event date - build a Luxon local datetime in that timezone - convert to UTC - call `createBodygraph(name, dateUtc, location)` ### Preferred UTC resolver Use the deployed helper described in `astrology-location-time-utc` when you need a reliable conversion from local birth data: ```bash curl -s 'https://transit-list-demo.apps.poofc.com/api/time/resolve?date=1985-09-26&time=07:14&location=London,%20England' ``` This returns the resolved timezone, UTC ISO timestamp, and transit-style UTC date string. For HD Prism generation, the key thing is the correct UTC instant. ### Generate through the live API For Astral Hermes tenants or any tool/API caller that only needs chart JSON, prefer the tenant-safe route. It is JSON-only and avoids the older PDF-report side effect: ```bash curl -sS -X POST 'https://hdprism.apps.poofc.com/api/tenant/bodygraph' \ -H 'Content-Type: application/json' \ -d '{"name":"Example Person","birthDate":"1985-09-26","birthTime":"07:14","location":"London, England"}' ``` The response contains `{ ok, resolved, summary, bodygraph }`. If `location` is supplied without `timeZone`, the API resolves UTC through `transit-list-demo` `/api/time/resolve`. If you want the exact legacy JSON path used by the app/PDF report generator, call the deployed/local bodygraph endpoint, but remember it is backed by the PDF report route and may write a PDF: ```bash python - <<'PY' import requests, json payload = { "name": "Example Person", "birthDate": "1985-09-26", "birthTime": "07:14", "location": "London, England", "timeZone": "Europe/London" } r = requests.post('http://localhost:3005/api/bodygraph', json=payload, timeout=90) print(r.status_code) print(json.dumps(r.json(), indent=2)[:4000]) PY ``` ### Generate internally from source helpers If you need a scriptable internal workflow, mirror production: 1. resolve UTC birth instant 2. call `createBodygraph(name, dateUtc, location)` 3. optionally attach provenance fields like `timezoneUsed` and `birthDateTimeUTC` 4. compute `chartFingerprint` 5. persist using `createSavedChart(...)` if the task requires saving Relevant helpers: - `createBodygraph(...)` - `computeChartFingerprint(...)` - `createSavedChart(...)` ## Part 3: KB-augmented reading workflow When Alex asks to compare the current HD Prism reading with a version grounded in the Human Design knowledge base, use this workflow instead of only calling the existing LLM reading generator: 1. Pull chart facts from the tenant API `POST /api/tenant/fact-pack` or from a saved chart's `chart_json`; never invent type/profile/authority/gates. 2. Use the chart facts to select wiki pages under `/home/avalon/wiki-human-design`, especially: - `queries/surface-analysis-first-pass.md` for reading sequence and guardrails. - `concepts/projector.md`, `generator.md`, etc. for type/aura. - `concepts/
-center.md` pages for open/defined center mechanics. - `concepts/profile-*.md` pages for profile-specific process. - `concepts/split-definition.md` for split/bridge interpretation. - gate pages such as `concepts/gate-43.md` when active gates have dedicated KB pages. 3. Read the relevant KB files directly and synthesize in the pattern: **chart fact → KB principle → chart-specific interpretation → practical guardrail**. 4. Keep Strategy and Authority primary. The KB repeatedly frames mind/open centers/bridges as outer-authority or conditioning fields, not decision-makers. 5. Include an explicit “Knowledge-base spine used” list so the output can be compared against HD Prism’s current non-KB reading. 6. If the current wiki lacks a dedicated page for an important gate (for example a Personality Sun gate), say so and interpret only from available chart mechanics/hanging-gate context rather than inventing gate lore. 7. Save longer experimental readings to a Markdown file when useful, then give Alex the path plus a concise preview. Useful live/reference calls: ```bash curl -sS -X POST 'https://hdprism.apps.poofc.com/api/tenant/fact-pack' \ -H 'Content-Type: application/json' \ -d '{"name":"Example Person","birthDate":"1985-09-26","birthTime":"07:14","location":"London, England"}' ``` For app-cached entity descriptions (not the external wiki KB), the batch reference API expects `items` and uses `chart_type`, not `type`: ```json { "items": [ {"entityType": "chart_type", "entityId": "Projector"}, {"entityType": "authority", "entityId": "Emotional"}, {"entityType": "profile", "entityId": "6/2"}, {"entityType": "channel", "entityId": "23-43"} ] } ``` Do not send `{ "references": [...] }` or `{ "entityType": "type" }`; the tenant reference route returns errors like `Missing items array` or `Invalid entityType: type`. ## Part 4: Human Design Environment Environment is derived from **Design South Node**, not Design Sun. Rules: - `Color` chooses the environment family: 1 = Caves 2 = Markets 3 = Kitchens 4 = Mountains 5 = Valleys 6 = Shores - `Tone < 4` => left orientation / strategic subtype - `Tone >= 4` => right orientation / receptive subtype Typical labels look like: - Selective Caves - Internal Markets - Wet Kitchens - Active Mountains - Narrow Valleys - Natural Shores If `environment` is missing from stored JSON, derive it from `chart_json.activations.Design.SouthNode`. ## Verification Checklist - [ ] Confirmed the active DB path before querying. - [ ] Read schema before assuming column names. - [ ] For existing charts, verified whether data came from `chart_json` or a derived calculation. - [ ] For new charts, converted local birth time to UTC using location-aware timezone logic. - [ ] When using the live API, got HTTP 200 and inspected returned JSON. - [ ] If saving code changes, rebuilt/restarted the affected app and tested again. ## Common Pitfalls 1. Querying the wrong SQLite file. 2. Assuming the server timezone equals the user's birth timezone. 3. Using fixed offsets instead of historical timezone resolution. 4. Using Design Sun for Environment instead of Design South Node. 5. Assuming all saved charts already store the newer metadata fields. 6. Returning paraphrased reading text when the request was to pull the exact stored reading.