pp-airframe
Aircraft forensics from open public records — tail-number dossiers, fleet research, model-level safety, and NTSB event archaeology. Trigger phrases: `look up tail number`, `who owns this plane N…`, `what aircraft does <company> own`, `safety record of <aircraft model>`, `accident history for`, `crash history for <aircraft model>`, `find aircraft registered to`, `NTSB event ERA…`, `use airframe`, `run airframe`. Secondary (day-of only, requires flight-goat + within 72hr of departure): `is UA<flight> safe`, `what plane is <flight>`.
What this skill does
<!-- GENERATED FILE — DO NOT EDIT.
This file is a verbatim mirror of library/developer-tools/airframe/SKILL.md,
regenerated post-merge by tools/generate-skills/. Hand-edits here are
silently overwritten on the next regen. Edit the library/ source instead.
See the repository agent guide, section "Generated artifacts: registry.json, cli-skills/". -->
# airframe — Printing Press CLI
## Prerequisites: Install the CLI
This skill drives the `airframe-pp-cli` binary. **You must verify the CLI is installed before invoking any command from this skill.** If it is missing, install it first:
1. Install via the Printing Press installer. It defaults binaries to `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows:
```bash
npx -y @mvanhorn/printing-press-library install airframe --cli-only
```
2. Verify: `airframe-pp-cli --version`
3. Ensure the reported install directory is on `$PATH` for the agent/runtime that will invoke this skill.
If the `npx` install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.3 or newer):
```bash
go install github.com/mvanhorn/printing-press-library/library/developer-tools/airframe/cmd/airframe-pp-cli@latest
```
If `--version` reports "command not found" after install, the runtime cannot see the binary directory on `$PATH`. Do not proceed with skill commands until verification succeeds.
## The two-tier model (read this first, every invocation)
| Tier | Dataset | Install requirement | Answers questions like |
|------|---------|---------------------|------------------------|
| **1** | FAA Aircraft Registry | **none** — just `airframe-pp-cli` | "Who owns N12345?" • "How old is this plane?" • "What aircraft does Berkshire Hathaway own?" • "What type is this Mode-S code?" |
| **2** | NTSB CAROL accident database | **`mdbtools` package** | "How safe is a Cessna 172?" • "Crash history for the Boeing 737 MAX 8" • "Has tail N12345 ever been in an incident?" • "Probable cause of event ERA22LA001" |
`airframe flight <ident>` additionally requires `flight-goat-pp-cli` installed + `FLIGHT_GOAT_API_KEY_AUTH` set, **and only works within ~72 hours of departure** (airlines don't assign a specific tail to a flight before then). For pre-purchase or pre-booking "is my flight safe" questions, use a Tier 2 model-level lookup with the equipment type from the booking site.
## Step 0 — Always run doctor first
Before answering any user question, run:
```bash
airframe-pp-cli doctor --json
```
Parse the JSON to determine:
- `db_exists` — has the user ever synced?
- `sync_meta` — which sources (faa_master, ntsb_avall) are present and how fresh?
- `mdbtools.detected` — can we serve Tier 2 questions?
- `flight_goat.detected` — can we serve `flight <ident>` questions?
**Branch from here** based on what the user actually asked.
## Decision tree (use this to drive every user interaction)
### A) User asks a Tier 1 question and Tier 1 is missing
*Example: "Who owns N628TS?" but `airframe-pp-cli doctor` shows db_exists=false or sync_meta is empty.*
1. Tell the user: "I need to download the FAA registry first (~80 MB, ~30 seconds, no setup needed)."
2. Offer to run `airframe-pp-cli sync` for them.
3. After sync completes, answer their original question.
### B) User asks a Tier 1 question and Tier 1 is ready
Just answer it directly:
```bash
airframe-pp-cli tail N628TS
airframe-pp-cli owner "Berkshire" --limit 20
```
### C) User asks a Tier 2 question (safety / accident / NTSB) and **`mdbtools` is missing**
*This is the most important branch — handle it with care.*
Surface a clear explanation:
> "To answer that, I need NTSB accident data, which requires the `mdbtools` package (NTSB ships their data in Microsoft Access format). It's a one-time install — would you like me to install it for you?"
If the user says yes, detect their OS and run the right command:
```bash
# Detect OS
uname -s # → "Darwin" for macOS, "Linux" for Linux
# Detect Linux distribution if Linux
cat /etc/os-release 2>/dev/null | grep -E '^ID='
```
Then propose **before running**:
| OS detected | Command to run |
|---|---|
| macOS (`Darwin`) | `brew install mdbtools` |
| Ubuntu / Debian (`ID=ubuntu`, `ID=debian`) | `sudo apt update && sudo apt install -y mdbtools` |
| Fedora (`ID=fedora`) | `sudo dnf install -y mdbtools` |
| RHEL / Rocky / Alma (`ID=rhel`/`ID=rocky`/`ID=almalinux`) | `sudo dnf install -y mdbtools` |
| Arch (`ID=arch`) | `yay -S --noconfirm mdbtools` *(AUR — needs `yay` or `paru`; if neither is present, tell the user to install one first)* |
**Important:** never run `sudo` commands without first showing the user what you plan to run and confirming. The `--noconfirm` for `yay` is OK because the user has already opted in once.
After `mdbtools` installs, run:
```bash
airframe-pp-cli sync --source all
```
Then answer the original question.
### D) User asks a Tier 2 question and `mdbtools` is present but NTSB hasn't been synced
*`doctor` shows `mdbtools.detected=true`, but `sync_meta` has no `ntsb_avall` row.*
Tell the user: "I have the NTSB ingest tool installed but haven't synced the data yet. Would you like me to run that now? It's ~90 MB and takes about a minute."
If yes:
```bash
airframe-pp-cli sync --source ntsb
```
### E) User asks a flight-ident question — **first, check the 72-hour gate**
*Examples: "Is UA1234 safe?", "What plane will I be on for AA200?", "Is my flight on DL5678 tomorrow OK?"*
**Critical context:** Airlines don't assign a specific tail to a flight until ~48–72 hours before departure. If the user is more than 72 hours from their flight (or shopping a ticket they haven't booked yet), looking up the specific tail is **impossible** — there is no tail yet. Don't burn a flight-goat call on it.
**Step 1 — establish when the flight is.** Ask the user (or infer from context):
> "When is the flight? Tail assignments are made 48–72 hours before departure — if you're shopping or it's further out than that, I'll point you at the model-level safety lookup instead, which is more reliable for that horizon."
**Step 2 — branch:**
- **Flight is >72 hours away or hypothetical** → recommend the model-level fallback. Most airline booking sites tell you the equipment type (e.g. "Boeing 737 MAX 8" or "Airbus A321neo"). Run:
```bash
airframe-pp-cli model "Boeing 737 MAX 8"
```
This answers the user's underlying question ("is the type of plane I'll be on safe?") and needs no flight-goat at all. (It still needs Tier 2 / mdbtools for safety data — fall through to branch C if missing.)
- **Flight is ≤72 hours away OR the user is asking about a flight that already happened (post-incident research)** → proceed with flight-goat resolution. Continue to step 3.
**Step 3 — flight-goat present? If not, install it.**
If `flight_goat.detected=false`, tell the user:
> "To resolve a specific flight ident (like UA1234) to a tail number, I need `flight-goat-pp-cli`. Would you like me to install it? It also requires a FlightAware AeroAPI key — that part you'll need to provide."
If yes:
```bash
go install github.com/mvanhorn/printing-press-library/library/travel/flight-goat/cmd/flight-goat-pp-cli@latest
```
**Step 4 — `FLIGHT_GOAT_API_KEY_AUTH` set? If not, explain the cost.**
If the env var is unset, tell the user that flight-goat routes through FlightAware's AeroAPI (paid service) and they'll need to sign up at flightaware.com/aeroapi to get a key. Don't push past without explicit direction.
**Step 5 — run the lookup.**
```bash
airframe-pp-cli flight UA1234
```
Note that the result may include **multiple recent tails** that have flown the same ident over the past 14 days — flight-goat returns the history, not just the next scheduled flight. For post-incident research, look at the date-aligned tail; for pre-departure curiosity, look at the most recent one.
## Commands
| Command | Tier | What it does |
|---|---|---|
| `sync [flags]` | both | Download Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.