Time-bounded and threshold-bounded risk detection across portfolio companies — finds items that are expiring soon, maturing soon, running low, or otherwise at risk. Surfaces what needs attention now, not what the data looks like in general.
Scan multiple companies for red flags and compute severity classifications (critical / warning / info). Builds on the carta-portfolio-query pattern.
No inputs required — this skill loops the full portfolio. Call list_accounts to get all corporation_pk accounts automatically.
Call list_accounts to get all portfolio companies. Filter to accounts where id starts with corporation_pk:. Extract up to 20 numeric corporation IDs. If more than 20 companies exist, ask the user to narrow scope.
For each company, these are the relevant checks:
fetch("cap_table:get:409a_valuations", {"corporation_id": corporation_id}) -- 409A expiry checkfetch("cap_table:get:cap_table_by_share_class", {"corporation_id": corporation_id}) -- option pool checkfetch("cap_table:get:convertible_notes", {"corporation_id": corporation_id}) -- note maturity check (summary includes maturity.nearest_date)fetch("cap_table:list:safes", {"corporation_id": corporation_id}) -- SAFE exposure checkThe gateway defaults to detail=summary for list commands. All four commands use summary mode — the convertible notes summary includes a maturity block with nearest_date and total_outstanding_debt for outstanding debt notes.
If the user asks about a specific check only (e.g. "any expiring 409As?"), fetch only the relevant command per company.
Parallel execution: The
fetchtool hasreadOnlyHint=true, so Claude Code executes parallel fetch calls concurrently. Issue ALL fetch calls for ALL companies in a single response — do NOT loop company-by-company. See Workflow Step 2.
From 409A: expiration_date, price, effective_date
From cap table option plans: available_ownership, name
From convertible notes (summary): maturity.nearest_date, maturity.total_outstanding_debt, by_status, by_type
Call list_accounts to get all corporation_pk accounts. Extract up to 20 numeric corporation IDs.
Issue ALL fetch calls for ALL companies in a single response — do NOT loop company-by-company. Each fetch call is independent and will execute concurrently.
For example, with 5 companies and all 4 checks, issue all 20 fetch calls at once:
fetch("cap_table:get:409a_valuations", {"corporation_id": 1})
fetch("cap_table:get:cap_table_by_share_class", {"corporation_id": 1})
fetch("cap_table:get:convertible_notes", {"corporation_id": 1})
fetch("cap_table:list:safes", {"corporation_id": 1})
fetch("cap_table:get:409a_valuations", {"corporation_id": 2})
fetch("cap_table:get:cap_table_by_share_class", {"corporation_id": 2})
... (all companies)If the user asks about a specific check only (e.g. "any expiring 409As?"), issue only the relevant command per company — but still all companies in one response.
Apply severity thresholds to the results for each company:
| Check | Critical | Warning | Info | Rationale |
|---|---|---|---|---|
| 409A expiry | No 409A on file, or expiration_date in the past | expiration_date within 90 days | expiration_date within 180 days | 90 days = standard board reporting cycle; 180 days = early warning for planning |
Companies with no 409A data should never be silently skipped — always include them in the output as a distinct category.
| Check | Critical | Warning | Info | Rationale |
|---|---|---|---|---|
| Option pool | available_ownership < 2% | available_ownership < 5% | available_ownership < 10% | 5% is industry floor for meaningful hiring capacity; <2% is effectively exhausted |
| Check | Critical | Warning | Info | Rationale |
|---|---|---|---|---|
| Note maturity | maturity.nearest_date in the past | maturity.nearest_date within 90 days | maturity.nearest_date within 180 days | 90 days = typical negotiation window for extension or conversion |
Use maturity.nearest_date and maturity.total_outstanding_debt from the convertible notes summary. These fields are pre-filtered to outstanding debt notes by the backend.
| Check | Critical | Warning | Info | Rationale |
|---|---|---|---|---|
| SAFE exposure | — | total outstanding SAFEs > 20% of last known valuation cap | — | 20% = significant dilution risk at conversion |
Sum outstanding SAFE amounts per company.
Present a summary dashboard (see Presentation section).
Required inputs: None — portfolio enumeration is automatic.
AI computation: Yes — severity classifications (critical, warning, info) for 409A expiry, option pool health, note maturity, and SAFE exposure are AI-derived. Trigger the AI computation gate (see carta-interaction-reference §6.2) before outputting any severity classifications or health assessments.
Subagent prohibition: Not applicable.
Format: Summary dashboard + detail table
BLUF lead: Lead with the count of companies scanned and the critical/warning/healthy breakdown.
Sort order: Severity (critical first), then urgency (nearest deadline first).
Date format: MMM d, yyyy (e.g. "Jan 15, 2026").
Portfolio Health Check — 12 companies scanned
Critical (2):
- Beta Inc: 409A EXPIRED (expired Jan 14, 2025, 63 days ago)
- Gamma Corp: Option pool at 1.2% available
Warning (3):
- Acme Corp: 409A expires in 37 days (Apr 24, 2025)
- Delta LLC: Convertible note matures in 45 days
- Epsilon Inc: Option pool at 4.1% available
Healthy (7): Alpha, Zeta, Eta, Theta, Iota, Kappa, Lambda| Company | Issue | Severity | Details | Action Needed |
|---|---|---|---|---|
| Beta Inc | 409A Expired | Critical | Expired Jan 14, 2025 | Order new 409A |
| Acme Corp | 409A Expiring | Warning | Expires Apr 24, 2025 (37 days) | Schedule valuation |
78eff87
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.