hd-prism-chart-data-workflows

/home/avalon/.hermes/skills/software-development/hd-prism-chart-data-workflows/SKILL.md · raw

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

Important source files

Read these first:

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:
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;"
  1. Check whether a full reading already exists:
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='<fingerprint>'
ORDER BY datetime(created_at) DESC;"
  1. 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:
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=?', ('<chart-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
  1. Verify completion in SQLite and export if needed:
sqlite3 -json descriptions.sqlite "
SELECT id,status,sections_total,sections_completed,created_at,updated_at,error_message
FROM readings
WHERE chart_fingerprint='<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:

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:

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:

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:

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:

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:

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>-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:

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:

{
  "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

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.