personal-tax-prep-coordination
Coordinate the user's annual US personal income tax return — gather W-2, 1099, 1095, brokerage crypto and foreign-account data, fill the Preparer's organizer questions, and queue the upload bundle for the Preparer's secure portal (TaxDome / Drivetime / SafeSend / etc.). Triggers: "task: taxes" calendar title, "do my taxes" / "tax organizer" Slack DM, Oren Hen / TaxDome / Preparer name, late-January vendor-1099 wave, March-April state+federal deadlines, July-October extension reminder storms. Anti-triggers: corporate/partnership returns, single-vendor portal work without coordination, post-filing read-only summaries.
- License 许可
- MIT
- 最近更新
- 2026-11-11
- Stars
- ★ 6
- Forks
- 0
01 前言 Front Matter
- name
- personal-tax-prep-coordination
- description
- Coordinate the user's annual US personal income tax return — gather W-2, 1099, 1095, brokerage crypto and foreign-account data, fill the Preparer's organizer questions, and queue the upload bundle for the Preparer's secure portal (TaxDome / Drivetime / SafeSend / etc.). Triggers: "task: taxes" calendar title, "do my taxes" / "tax organizer" Slack DM, Oren Hen / TaxDome / Preparer name, late-January vendor-1099 wave, March-April state+federal deadlines, July-October extension reminder storms. Anti-triggers: corporate/partnership returns, single-vendor portal work without coordination, post-filing read-only summaries.
02 资源文件 9
- 参考文档references/2025-document-checklist.md4.4 KB
- 参考文档references/file-watcher-cron-pattern.md15.1 KB
- 参考文档references/headless-portal-login-blockers.md8.3 KB
- 参考文档references/preparer-notes.md3.9 KB
- 脚本scripts/fetch_tax_season_history.sh5.2 KB
- 脚本scripts/render_draft_reply.py5.4 KB
- 脚本scripts/taxdome_prefill_organizer.py8.6 KB
- 脚本scripts/taxdome_upload_documents.py10.9 KB
- 脚本scripts/taxdome_verify_documents.py4.0 KB
03 SKILL.md 正文
personal-tax-prep-coordination
Drive the user's annual US personal income tax return at the coordination layer — NOT the Preparer. Do NOT file, do NOT calculate AGI, do NOT send email until the user types EMAIL APPROVED.
Why this skill exists
The user has a recurring annual workflow: their Preparer (currently Oren Hen, Enrolled Agent at Oren Hen EA, Inc., TaxDome portal at https://orenheneainc.taxdome.com/login) sends a stream of reminder and Missing-Data emails between January and October. The user has historically replied with one-liners ("Ok will do", "Yes will do", inline answers below each question) and uploaded PDFs to the secure portal. 2025 cycle (verified 2026-07-18) was still pending with the Oct 15 extension already filed.
The gap: when a calendar reminder or Slack event says "task: taxes", the right response is NOT to start downloading PDFs. It is to ask "what exactly is the user asking for?", then reconstruct the workflow history from Gmail / Drive / Calendar, then build the checklist + draft. This skill encodes that sequence so the next session doesn't re-derive it.
Canonical workflow (one year at a time)
Phase 0 — Decide what "doing the taxes" actually means
Sources of truth, in priority order:
- The most recent Preparer email asking for an action ("Upload all 2025 tax documents…", "Finalize Organizer…", "Submit Organizer…").
- The calendar entry ("task: taxes" or similar — usually a short reminder the user created days before the deadline).
- A Slack DM / thread the user just forwarded with a vague "do my taxes" prompt.
Do NOT skip Phase 0 and start downloading PDFs. The Preparer has already told you what they need; reuse that as the scope.
Phase 1 — Reconstruct prior-year workflow from Gmail
Pre-flight in parallel: memory-search, google-workspace (for gog gmail thread get). Then run:
GOG="gog -a $USER@gmail.com"
$GOG gmail search "from:<preparer-domain> newer_than:9m" --max 20 # Preparer emails
$GOG gmail search '"IMPORTANT TAX RETURN DOCUMENT AVAILABLE"' # vendor 1099s
$GOG gmail search "1095" '"Form 1095"' # health insurance
$GOG gmail search '"W-2" Snap' '"Wage and Tax Statement"' # W-2 trail
$GOG gmail search '"Confirmation of invoice"' # payment confirmations
$GOG gmail calendar list --from $(date -v-1y +%Y-%m-%dT%H:%M:%SZ) \
--to $(date +%Y-%m-%dT%H:%M:%SZ) --json --max 200
For each Preparer thread, capture: sender address, invoice numbers referenced, payment status, deadlines (April 15 / Oct 15 / state-equiv), and organizer-question wording. Treat the most recent "Missing Data Request" or "Finalize Organizer" email as the canonical template — Oren Hen has used the same numbered-section format every year since at least 2020.
Cross-validate payment status separately:
$GOG gmail search 'from:paypal.com <preparer>' 'from:venmo.com <preparer>'
For each Preparer invoice number, verify it appears in a Payment confirmation thread. "I think I already paid" is not proof — only the exact invoice number in a Payment confirmation thread is. Verified 2026-07-18: invoice 1002418 ($80 extension fee) was flagged overdue 11 times in May-June 2026; user replied "Think I already paid this?"; the only Payment confirmation we found was for a different invoice (1002106, $850 prep fee, paid March 2026). Always cite the exact invoice number.
Phase 2 — Reconstruct vendor tax-document history from Drive
DRIVE="gog -a $USER@gmail.com drive"
$DRIVE search "<year> 1099" "<year> W-2" "Schwab <year>" "Wealthfront <year>" \
"Fidelity <year>" "Morgan Stanley <year>" "1095 <year>" \
--max 10 --plain
$DRIVE search '"<Preparer> <year>"' 'TaxDome' '"Tax Documents"' \
--plain --max 10
Compare Drive vs Phase-1 emails. Output a sparse matrix:
| # | Doc | Source | In Drive? |
|---|---|---|---|
| 1 | 2025 W-2 | Snap Inc Workday | ❌ |
| 2 | 2025 1095-C | Snap Inc Workday | ❌ |
| 3 | 2025 1099-R | Fidelity NetBenefits | ❌ |
For vendors the user reports every year (Morgan Stanley, Schwab, E*TRADE, Wealthfront, Wells Fargo), assume the same vendor list will apply. For NEW vendors, call them out explicitly.
Phase 3 — Build the document checklist
Use references/<year>-document-checklist.md (or its year-current copy). The skeleton is fixed year-to-year:
- Federal W-2 (employer)
- Federal 1095-C (employer-sponsored health)
- Federal 1099-INT (per bank)
- Federal 1099-DIV (per brokerage)
- Federal 1099-B (consolidated broker statements)
- Federal 1099-R (Fidelity / Vanguard / employer 401k plan)
- Federal 1098 (mortgage interest)
- State equivalents (e.g. CA FTB 1099-G for state refund)
- Crypto: Form 8949 + Schedule D from each exchange
- Foreign accounts (FBAR / Form 114 + Form 8938): bank + crypto peak balances in original currency
- Estimated tax payment confirmations (federal + state), 4 quarterly dates
- Charitable contribution receipts
- K-1s (if any pass-through interests)
The per-vendor portal list and exact organizer-question wording live in references/preparer-notes.md so next session doesn't re-derive them.
Phase 4 — Build the draft reply to the Preparer
Use the raw prior-year Missing Data Request as the template. The Preparer expects the user to type answers inline below each question (e.g. "1a — closed. 2a — yes, 1099-DIV received"). Do NOT change the question wording unless there is a strong reason — the Preparer's parser expects the exact section numbering.
The user's preference is one-liner replies (verified 2026-07-18 thread 19f715fbb121bc06: "Ok will do"). Do NOT inflate the email to a multi-paragraph reply unless the Preparer asked a substantive question. Inflation wastes the Preparer's review time and the user's review credit on a draft.
Do NOT use any send primitive at this point. Stage the draft at /tmp/<preparer>-<year>-reply.txt and /tmp/<preparer>-<year>-upload-checklist.md, present for review. Send only on explicit EMAIL APPROVED per SOUL.md email-approved-gate. Do NOT invent a "soft-send" or "queue" path.
Phase 5 — Surface human blockers; do NOT chase "fully headless"
Most tax portals intentionally block headless login on the first navigation:
- TaxDome uses Cloudflare Turnstile on the first page load — headless Chrome UAs are on the deny list.
- Snap Workday is gated behind Okta SSO + the user's corporate SAML.
- Morgan Stanley / E*TRADE / Schwab / Wealthfront / Fidelity / Wells Fargo all require interactive SSO + captcha refresh.
The reliable pattern is one-time interactive sign-in so the session cookie persists, then headless thereafter. Surface this as a 1-shot blocker ("please log in to these N sites in your browser once so the session cookie sticks"). Do NOT chase a "fully headless" fantasy that requires the agent to interact with captchas.
For password retrieval: Apple Passwords is the canonical source on this Mac. It is not readable from a Hermes session (Apple keeps the DB behind the user's screen-lock unlock + per-process authorization). Canonical path: open Passwords.app, copy, paste into the portal manually. Tell the user this in one line — do NOT enumerate alternate storage paths or propose workarounds.
Downloads folder convention (2026-07-19): the user prefers ~/Downloads/<preparer-slug> <year>/ for tax PDFs (e.g. ~/Downloads/tax 2025/). Mirror that folder into tax <year> Drive folder. Do NOT use /tmp/... — the user wants the files to survive across sessions and be visible in Finder. Stage the folder before any portal work; the file-watcher cron (Phase 5.5) will pick up new PDFs automatically.
Phase 5.5 — Proven headless drive path AFTER the one-time interactive login
Once the user has signed in to each portal in their existing visible Chrome or Aside window, the next layer is to drive downloads headlessly. Verified 2026-07-18 → 2026-07-19 session:
-
Dump decrypted session cookies via
browserclaw cookies decrypt— the bypass-ABE claim in earlier revisions of this skill was wrong. With the right flags, browserclaw handles v20 App-Bound Encryption on macOS:~/.local/orch-venv/bin/browserclaw cookies decrypt \ --db "$HOME/Library/Application Support/Google/Chrome/Default/Cookies" \ --output /tmp/<preparer>-<year>-cookies-chrome.json \ --keychain-service 'Chrome Safe Storage' --keychain-account 'Chrome' \ --summarySame for Aside (
--db "$HOME/Library/Application Support/Aside/Default/Cookies",--keychain-service 'Aside Safe Storage',--keychain-account 'Aside'). Filter to tax domains with--domain-filter '%<portal>%'if you only need one site. Verified 2026-07-19: 1059 Chrome + 553 Aside cookies, allvaluefields populated. Ifvalueis empty, the keychain flags are wrong (don't assume v20 is unsupported — re-check the flags first). -
Drive TaxDome directly via Playwright + bundled Chromium-for-Testing — TaxDome does NOT fingerprint-bucket sessions, so cookie replay works. Use
context.add_cookies()after normalizingexpires(skip the field for cookies withexpires_utc=0; convert>1e12from microseconds). The dashboard, organizer (12-step), Documents upload, and billing pages are all driveable headlessly. -
For Schwab / Fidelity / Morgan Stanley / Wells Fargo / E*TRADE / Wealthfront — DO NOT try Playwright. They TLS-fingerprint the browser. Even with fresh valid cookies, you'll land on
SessionExpired. Proven alternatives:- Drive the user's visible Chrome via AppleScript — but
Allow JavaScript from Apple Eventsis OFF by default; requires the user to enable it inView → DeveloperAND relaunch Chrome. - Wait for the user to download PDFs manually into
~/Downloads/<preparer> <year>/. The file-watcher cron (next step) picks them up. This is the path the 2025-07-19 session used successfully. - Do NOT loop on retries — they all fail the same way (verified 8+ attempts across two sessions).
- Drive the user's visible Chrome via AppleScript — but
-
Coordinate with active Aside MCP sessions. Before driving, probe:
curl -fsS http://127.0.0.1:21420/healthreturnsrunningSessionCount. If> 0, another chat is driving the user's Aside — DO NOT spawn a competing browser session. Pass the URL playbook (/tmp/<preparer>-<year>-portal-playbook.md) and the local staging path (/tmp/<preparer>-<year>/raw/) to that chat and let it drive the downloads in parallel with this chat handling Drive / Gmail / calendar work. IfrunningSessionCount == 0, the daemon is up but no other chat is currently using it — safe to drive from this session. -
File-watcher cron for the user's manual downloads (pattern in
references/file-watcher-cron-pattern.md). Polls~/Downloads/<preparer> <year>/every 2 min for new PDFs (find -mmin -5), mirrors to Drive + TaxDome Documents, posts a one-line Slack confirmation per file. Self-cancels after 4h or after all 10 portal forms are present. Created in the 2026-07-19 session with cron jobad5ed0137d89(tax-2025). v2 update 2026-07-19 (tick 2): added the five-gotchas TaxDome Documents upload recipe — see "TaxDome Documents upload — concrete recipe" in that reference, and the standalone executable atscripts/taxdome_upload_documents.py. v3 update 2026-07-19 (tick 2 close): added three durability pitfalls — (1) the Hermes terminal wrapper scrubs find-printfAND compound predicates, so useenv -i … /usr/bin/find -printto bypass; (2) the cron bot is NOT a member of the SOUL-mandated home channel#ai-general(C0AJQ5M0A0Y), somcp__slack__conversations_add_messagereturns Failure-5gnot_in_channel— pinned channel is#all-$USER-ai(C09GRLXF9GR); (3) the cron--deliver 'slack:CHAN'field does NOT propagate into in-promptconversations_add_messagecalls. Hardened cron prompt template at the top of the reference now bakes all three in. Verified tick 2 end-to-end onad5ed0137d892026-07-19: 2 new PDFs (Wells Fargo 1099-INT + 1098-MORT) picked up, mirrored, Drive-uploaded, TaxDome-uploaded (OK / done shown), Slack-posted to C09GRLXF9GR, cron self-cancelled. Do not re-derive the data-test selectors or the webkitdirectory trap in a future cron prompt — they are codifying the working recipe. -
Cloudflare
_abck/ Akamaibm_szrotate every 5–10 min. Re-dump cookies right before each Cloudflare-fronted navigation, or drive the portal within 5 min of the dump.
This sequence (one interactive sign-in + file-watcher cron + driving only TaxDome headlessly) is fully headless after the one-time human unlock — no need to interact with captchas again.
Phase 6 — Send the staged email
After the user has (a) approved verbatim with EMAIL APPROVED or (b) explicitly edited answers, send via gog gmail reply <thread_id> --body-file /tmp/<preparer>-<year>-reply.txt. The thread_id is the Preparer's most recent unanswered email (confirm via gog gmail search first). Load email-drafting for the canonical gog send path — do NOT use Slack MCP.
After send, do NOT post a Slack summary unless the user initiated from Slack. Email is the channel; portal upload is the channel.
Phase 7 — End-state declaration
When (a) all 12+ documents uploaded to TaxDome, (b) organizer submitted, (c) any outstanding invoice (extension fee etc.) paid, (d) email sent — declare end-state and STOP. Do NOT try to e-file, calculate AGI, or push back to the Preparer. The Preparer owns return preparation; you own coordination.
Pitfalls
- "I think I already paid" is not proof. Cross-check against a Payment confirmation thread with the exact invoice number. See Phase 1 verified example.
- Do NOT chase fully headless portal login on the FIRST page load. Turnstile + SSO + Apple-Passwords make it impossible without screen-unlock + paste from the user's Passwords. One interactive session, then headless, is the durable path.
browser_navigate(Hermes MCP browser tool) routes through Browserbase, a data-center IP — Cloudflare blocks it on TaxDome-class portals. The user said it directly: "shouldnt need cloudflare if I'm using aside mcp". Use Aside MCP / Aside CLI / local Chrome AppleScript instead. Browserbase is fine for non-CF-fronted sites.- Apple Passwords cannot be queried —
aside repl applePasswords.*returns "No last-focused window",security find-generic-password -s "Aside Safe Storage"returns not found. The DB is encrypted-at-rest with a key the user must unlock interactively. Don't waste cycles on this — just ask the user to copy/paste. aside mcpis a stdio MCP server, NOT an HTTP one.claude mcp add aside-mcp -- aside mcpregisters it correctly. If registered ashttp://127.0.0.1:8013/mcpit will spawn and immediately exit onstdin-end(verified 2026-07-18). Symptom:claude mcp listshowsaside-mcp: ✘ Failed to connect. Fix: remove + re-add as stdio.browserclaw cookies decryptDOES handle Chrome v20 App-Bound Encryption on macOS when given the right keychain flags:--keychain-service 'Chrome Safe Storage' --keychain-account 'Chrome'. Verified 2026-07-19: dumped 1059 Chrome + 553 Aside cookies with allvaluefields populated. The earlier v20-blocks-browserclaw claim in this skill is wrong — that pitfall was based on a default-flag invocation that hit the wrong keychain. Always pass the keychain flags. Ifvalueis empty on a large dump, the keychain flags are wrong, not that v20 is unsupported.- Even with valid cookies, Playwright's bundled Chromium-for-Testing fails server-side TLS-fingerprint checks on Schwab / Fidelity / Morgan Stanley / Wells Fargo / E*TRADE. Symptom: cookies decrypt fine,
context.add_cookies()accepts them, navigation lands onLogin | SessionExpired. Root cause: these servers tie sessions to the browser's TLS fingerprint (not just cookies), so a fresh Chromium binary is treated as a new device. Real Chrome binary also fails because Playwright's CDP-driven launch still doesn't match the user's live session fingerprint. The only proven headless path for these portals is driving the user's existing visible Chrome (AppleScript + JS clicks), or polling for files in~/Downloads/<folder>/once the user downloads them manually. Don't loop on Playwright retries — they'll all fail the same way. - For portals you can't drive headlessly, use a file-watcher cron that polls
~/Downloads/<preparer> <year>/for new PDFs every 2 min and mirrors to Drive + TaxDome Documents + Slack. Pattern inreferences/file-watcher-cron-pattern.md. Verified 2026-07-19: 14 PDFs from Morgan Stanley / Schwab / Fidelity / Wells Fargo / Snap / Wealthfront were picked up within one tick. - AppleScript
make new tab at enddoes NOT activate the window (verified 2026-07-18, front app stayedcmux DEV). Use this pattern to add tabs without stealing focus. NEVERtell application "Google Chrome" to activatefrom a tax-prep session. - Aside daemon can be up but idle (
runningSessionCount: 0). Don't conclude "the user's other chat is driving Aside" until you've polled/health. IfrunningSessionCount == 0, drive freely. If> 0, hand off the URL playbook to whichever chat is active. - The user's preference is one-liner replies. Inflation wastes the Preparer's review time.
- Drive ≠ portal. A PDF in Drive does NOT mean it was uploaded to TaxDome. Always treat them as two separate endpoints.
gog gmail thread get --plaintruncates body for big threads. Use--plain --full(if supported) orgog gmail get <msg_id> --format full --jsonfor the actual body.- Organizer deadline ≠ upload deadline. Preparer wants docs uploaded ~7/30; the Oct 15 extension is the IRS hard date. Don't conflate the two.
- Do NOT try to be the Preparer. Do NOT fill Schedule D, compute AGI, or file. Route to the Preparer.
- Do NOT call
browser_click/browser_typefromaside repl. These primitives don't exist in the REPL (verified aside v1.26.713.1911, 2026-07-13). Usemcp__aside-mcp__*from a runtime that exposes them, or drive the page viapage.evaluate(...). See~/.hermes/skills/aside-browser-default/SKILL.mdfor the full REPL surface.
Extending for a new Preparer
- Replace site / portal references in
references/preparer-notes.md. - Replace the local-history defaults with the new Preparer's prior-year pattern.
- If the new portal uses a different cookie / SSO mechanism, add a sub-skill under
devops/orproductivity/rather than overloading this one. - Phase ordering (0-7) is portable; per-Preparer detail is not.
Support files
references/<year>-document-checklist.md— year-specific checklist, vendor list, answer template. Refresh every January.references/preparer-notes.md— Oren Hen facts: TaxDome URL, portal quirks, invoice-numbering convention, organizer-question template evolution.references/headless-portal-login-blockers.md— canonical "which portals block headless + what bypass the user has approved" — next session doesn't have to re-probe.references/file-watcher-cron-pattern.md—~/Downloads/<preparer> <year>/poll-and-mirror cron for portals you can't drive headlessly (verified 2026-07-19, job idad5ed0137d89). v2 update 2026-07-19 adds the five-gotchas TaxDome Documents upload recipe + Drive-dedup pitfall + find-printf macOS BSD pitfall.scripts/fetch_tax_season_history.sh— one-shot Gmail + Drive + Calendar fetch. Runs Phases 1+2; dumps/tmp/<preparer>-<year>-history.jsonfor Phase 3.scripts/render_draft_reply.py— renders/tmp/<preparer>-<year>-reply.txtfrom the in-memory answer map (or interactively on stdin).scripts/taxdome_prefill_organizer.py— headlessly pre-fill the TaxDome Yes/No organizer (12 steps, ~75 questions). Verified 2026-07-19 against organizer 6044459. Reads cookies + answer-map JSON, walks steps, does NOT submit.scripts/taxdome_upload_documents.py— headless Playwright upload of one or more PDFs to TaxDome "Client uploaded documents". Verified 2026-07-19 against 13 PDFs (Wells Fargo, Fidelity, Morgan Stanley, Schwab, Snap, Wealthfront). Codifies the data-test selectors, the webkitdirectory trap, the modal vs page "Upload" button distinction, and the "Done = success" sentinel. Use this from any file-watcher cron tick; do NOT re-derive the upload recipe in cron prompts.scripts/taxdome_verify_documents.py— reads back the TaxDome Documents page via Playwright, prints the PDF inventory to stdout, screenshots to/tmp/tax2025/shots/taxdome-verify-<ts>.png. Used to confirm uploads actually persisted past the modal "Done" signal (which only confirms the HTTP POST reached TaxDome).
Failure modes / when NOT to use this skill
- The user has not filed US personal income tax (non-resident alien, lives outside the US → different forms). Verify SSN / ITIN on a recent 1040 before firing.
- Corporate / partnership / trust return. Route through the relationship manager at the user's accounting firm instead.
- The user is mid-audit (IRS / FTB notice + response window). Refer to the audit notice thread and the Preparer's audit-representation engagement. This skill is purely for annual filing.
- The Calendar entry is just a category label — confirm the user meant "do my taxes" before starting Phase 1.
04 同仓库更多 Skills
instinct
Use when the user invokes /instinct or /in, or asks to "message Instinct", "ask Instinct", "tell Instinct", "check Instinct", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.
hr
Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.
history-resume
Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.
grok
Alias for the canonical grokbot browser conversation workflow; /grok talks to the Grok bot the same way /dot talks to Dot.
codexa-bench
Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.
frontend-design
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.