Ryanhub - file viewer
filename: .cursor/skills/update-profile/SKILL.md
branch: main
back to repo
---
name: update-profile
description: >-
  Refresh Ryan's profile sources of truth. Fetches the canonical links in
  profile/links.md (ryanhub.org, GitHub, blog, project pages, repos) and folds
  in anything Ryan provides, then updates the factual profile/*.md files. Use
  when Ryan says update my profile, refresh my info, hit my links, I built X,
  add this project/role/skill, or sync my resume inventory.
---

# Update profile

Keep the factual `profile/` inventory accurate and current. Two inputs: Ryan's public links, and whatever Ryan tells you in the prompt. Output: edited `profile/*.md` source-of-truth files plus a short change report.

These are factual inventory files, not entity records. Do not touch IDs, `data/*.csv`, leads, contacts, or companies. No `sync_indexes.py` needed for profile-only edits.

## Read first

1. `profile/links.md` and `sources.md` for the canonical link list
2. The factual files you may edit: `profile/experience.md`, `profile/projects.md`, `profile/education.md`, `profile/leadership.md`, `profile/skills.md`, `profile/links.md`

Do not rewrite positioning files (`voice.md`, `target-thesis.md`, `company-fit-rubric.md`, `outreach-angles.md`, `weird-outreach.md`) unless Ryan explicitly asks.

## Workflow

1. Collect Ryan's stated updates from the prompt.
2. Build the fetch list from `profile/links.md`. Fetch each unique URL once.
   - Static pages (ryanhub.org/me, resume.pdf, blog, GitHub repos/profile): use WebFetch.
   - JS-heavy or login-gated (LinkedIn, Instagram, X): use Playwright MCP read-only if available, else skip and note it.
   - Skip mirrors and duplicate links (e.g. a GitHub repo and its RyanHub mirror count once).
3. Extract concrete facts: new or changed projects, repos, roles, dates, coursework, skills, writing, live URLs.
4. Reconcile each fact into the correct file (see mapping). Dedupe against what is already there.
5. Apply clear factual additions and corrections directly. Ask before deleting content or doing a large rewrite.
6. If new URLs surfaced, add them to `profile/links.md` (and the external table in `sources.md` if it is a primary source).
7. Print the change report.

## File mapping

| New information | File |
|-----------------|------|
| Jobs, internships, research, collaborative roles | `profile/experience.md` |
| Projects, repos, demos, writeups, live products | `profile/projects.md` |
| School, degree, GPA, graduation, coursework | `profile/education.md` |
| Clubs, presentations, community/teaching roles | `profile/leadership.md` |
| Languages, tools, domains, areas | `profile/skills.md` |
| Any public URL | `profile/links.md` |

## Rules

- No fabrication. Only add facts Ryan stated or that are verifiable from a fetched link. If a fetch fails, do not guess its contents.
- Match the existing format and headings of each file. Keep Ryan's voice (see `profile/voice.md`): concrete, plain, no buzzwords.
- Dedupe. Update an existing entry in place rather than adding a near-duplicate.
- Preserve facts you cannot verify. Do not delete an entry just because a link was unreachable this run.
- Prefer primary sources, work, and repos first; do not loop or re-fetch the same URL (see the efficiency rule).
- Plain text, no em-dashes.

## Change report

End with:

```
Profile update report

Fetched: <count> links (<count> skipped/unreachable: list)
Updated:
- profile/projects.md: added <X>, updated <Y>
- profile/skills.md: added <Z>
From Ryan's input:
- <what was applied>
Needs Ryan confirmation:
- <anything ambiguous or proposed deletions>
```