--- name: astrology-audit description: Render the current astrology / HD / synthesis reading pipeline as a labeled flowchart PNG, so Alex can audit which skills were called in what order and inspect the SKILL.md context behind each step. Use whenever Alex asks to "audit", "show the pipeline", "show the flow", "show what skills you used", or wants to mutate the reading pipeline. version: 0.1.0 author: Hermes Agent + Alex license: MIT metadata: hermes: tags: [astrology, audit, pipeline, visualization, meta] related_skills: [astrology-reading-compose, astrology-lens-rulership-chains, astrology-lens-decans-36-faces, astral-chart-api, astral-tenant-kb, hd-prism-tenant-api, hd-deep-dive] --- # Astrology Audit A meta-skill. Renders the current astrology / HD / synthesis reading pipeline as a labeled PNG flowchart and emits a JSON legend (numeric node id → skill name → SKILL.md path → one-line role). Telegram-friendly: ship the PNG with `MEDIA:` and list the legend with file links underneath. ## Trigger phrases - "audit your astrology", "show the pipeline", "show the flow", "what skills did you use" - "diagram the astrology", "diagram the HD", "diagram the synthesis" - Anything where Alex is reviewing or about to mutate the reading pipeline before a fresh experiment ## How it works `scripts/render_pipeline.py ` where mode ∈ `{astro, hd, synthesis}`. 1. The script holds a structured `PIPELINES` dict — one entry per mode — with nodes (id, title, skill, role) and edges. 2. Renders the graph with Pillow to a PNG at `/tmp/astro-pipeline-.png`. 3. Walks each node's `skill` field, resolves it under `~/.hermes/skills/**//SKILL.md`, and emits a JSON legend with the absolute path. Nodes without a backing skill (pure prose / weave steps) are marked `terminal` and have `skill_md: null`. The script's `PIPELINES` dict is the **single source of truth** for what the pipeline currently is. Mutating the pipeline means editing that dict and re-running — the diagram and legend update together. ## How to deliver in Telegram 1. Run the script for the right mode. 2. Send the PNG with `MEDIA:/tmp/astro-pipeline-.png`. 3. Below the image, print a numbered legend where each node's SKILL.md is exposed as a **real https hyperlink** to the skill-viewer app (`https://skills.apps.poofc.com/skills/`), NOT as a `MEDIA:` attachment. Format per node: `**[N] Title** — one-line role. [](https://skills.apps.poofc.com/skills/)` 4. End with a one-liner offering to mutate the pipeline. ### Why URLs, not MEDIA attachments (PITFALL, learned 2026-05-25) The first version of this skill delivered each SKILL.md as `MEDIA:/abs/path/to/SKILL.md`. **This does not work** — Telegram (and the Hermes gateway in front of it) only renders `MEDIA:` for images / audio / video. Raw `.md` paths are silently dropped or rendered as inert text. The user cannot tap them. The fix is the **skill-viewer** app (`~/apps/skill-viewer`, PM2 `skill-viewer`, port 4036) reverse-proxied at `https://skills.apps.poofc.com/skills/` — renders any SKILL.md as themed HTML on demand. The audit script's JSON legend already includes `skill_url` for every node; use that field, not `skill_md`, for the user-facing reply. If the viewer is down or the subdomain isn't wired yet, **say so explicitly** and fall back to pasting the skill name + local path as plain text. Do NOT silently emit broken `MEDIA:` lines. ## Modes - **astro** — astrology-only reading (rulership-chains lens, optional decans) - **hd** — HD-only reading (HD Prism + optional deep dive) - **synthesis** — both branches + synthesis weave (the path that produced Milad's "full picture") Pick mode from context. If user just says "audit", default to whatever the most recent reading was; if unclear, ask. ## Mutating the pipeline When Alex says "let's try X next" / "swap rulership for decans" / "add a transit overlay step": 1. Edit `scripts/render_pipeline.py` PIPELINES dict — add/remove/reorder nodes, edit `layout`, edit `edges`. 2. Re-run to confirm the diagram still reads cleanly. 3. Keep numeric ids stable across mutations *within a session* so Alex's notes about "step 5" don't drift mid-conversation. Renumber only on his explicit request. ## Hard rules - Always emit BOTH the diagram (PNG) AND the legend with **real https hyperlinks** to `skills.apps.poofc.com/skills/`. Diagram alone is not auditable. - Never deliver SKILL.md content via `MEDIA:` — Telegram does not render markdown attachments (see PITFALL above). Use the viewer URL. - Never inline the contents of a SKILL.md into the legend — the user wants to open the actual file. - If a `skill` field in `PIPELINES` doesn't resolve to a real SKILL.md, fix the skill name — don't silently emit `null` for a step that's supposed to be backed by a skill. - The script must remain runnable standalone (`python3 render_pipeline.py `) so it can be called from cron / verification scripts later. - **The diagram is DYNAMIC, not a one-off illustration.** Every call must re-render from the current `PIPELINES` dict — never draw a freehand image of the pipeline, never describe the flow in prose alone when an audit was requested. If the user has mutated the pipeline during the session, the next render must reflect that mutation. - **Delivery channel is Telegram-native, not a web viewer.** See `references/delivery-decision.md` — Alex explicitly rejected separate dashboards / viewer apps / admin pages for this workflow. Don't propose them again unless he asks. ## Verification - [ ] PNG saved at expected path - [ ] Every non-terminal node resolves to an existing SKILL.md - [ ] Legend numbers match the diagram exactly - [ ] Telegram delivery includes both the PNG and per-step file attachments ## Future - Optional `--lenses rulership,decans` flag to render an arbitrary lens combo from the command line - Highlight nodes that *actually fired* in the most recent reading (vs the static template), by reading from a per-session trace file - Add transit overlay / time-lord / nakshatra branches once those lenses ship ## See also - `references/skill-viewer-infra.md` — how the `https://skills.apps.poofc.com` legend links resolve, health checks, restart, and the fallback to plain-text file paths when the viewer is unavailable.