Skill: Roth Conversion RMD Analysis for Wealth Advisory
Overview
Generate a structured JSON comparison of Roth conversion versus RMD baseline for a private-wealth advisory client. The procedure queries an advisory API, resolves conflicting multi-source records, projects taxes and balances through a planning-horizon year, and produces a recommendation.
API Usage
- Obtain the advisory API base URL from the environment (commonly exposed as
API_BASE after the shared environment starts).
- Query all relevant endpoints for the given
client_id:
- Client profile and demographics
- Account holdings and custodian exports
- Tax-policy constants (brackets, rates, thresholds)
- RMD factors / uniform lifetime table
- Any source documents, life-insurance records, or trust candidates
- Conflicts are expected because records were imported from different systems. Keep every source value and its provenance tag for resolution.
Source Resolution Rules
Apply these hierarchies before using any data in calculations.
- Profile / demographic data (highest priority first):
SIGNED_PROFILE
ATTORNEY_MEMO
CUSTODIAN_EXPORT
CRM_NOTE
STALE_MARKETING_INTAKE
- Account / balance data (highest priority first):
CUSTODIAN_EXPORT
SIGNED_PROFILE
CRM_NOTE
Report the winning source tags in:
source_resolution.controlling_profile_source
source_resolution.controlling_account_source
Analysis Steps
1. Anchor dates and horizon
client_id and the planning horizon year come from the advisor request memo.
- Determine the client’s birth year / age from the resolved profile.
- Compute the first RMD year using the resolved tax-policy constants (e.g., SECURE 2.0 rules: age 73 for birth years 1951–1959, age 75 for 1960+).
2. Baseline scenario (no conversion)
- Project the resolved traditional retirement-account balance forward year by year through the horizon.
- Starting in the first RMD year, apply the applicable RMD factor each year to determine the required distribution.
- Tax each distribution using the resolved ordinary-income brackets.
- Accumulate the taxes →
baseline_rmd_tax_through_horizon.
3. Conversion scenario
- If the memo explicitly states "no conversion is requested" (or the client is clearly unsuitable), set all conversion amounts to
0 and skip to step 5, but still keep any baseline plan years in conversion_plan with zeroed amounts.
- Otherwise, build a staged conversion plan:
first_conversion_year is normally the current / next year.
conversion_years is the count of years over which conversions are spread.
conversion_years_positive equals conversion_years when conversion is positive; in no-conversion cases it may match the planned window but amounts must be 0.
annual_conversion_amount = total_converted / conversion_years, rounded to cents.
total_conversion_tax = sum of tax on each year’s converted amount, rounded to cents.
- After removing converted amounts, reproject the remaining traditional balance and its yearly RMDs.
- Accumulate post-conversion RMD taxes →
conversion_rmd_tax_through_horizon.
4. Savings and legacy projection
rmd_tax_savings_through_horizon = baseline_rmd_tax_through_horizon - conversion_rmd_tax_through_horizon.
- Allow a one-cent tolerance because intermediate year-by-year rounding can propagate.
- Project the Roth balance at horizon by growing the converted amounts.
- Project the remaining traditional balance at horizon.
- Set
heir_tax_profile:
MOSTLY_TAXABLE when the Roth balance is negligible (e.g., no conversion occurred).
MIXED_TAXABLE_AND_TAX_FREE when both Roth and traditional balances are materially positive.
MOSTLY_TAX_FREE when the traditional balance is negligible.
5. Recommendation
primary_action:
NO_CONVERSION when the memo explicitly says no conversion is requested, or when analysis shows conversion is unsuitable.
STAGED_ROTH_CONVERSION otherwise.
suitability:
SUITABLE for staged conversions.
DEFER for no-conversion recommendations.
risk_flag (choose the best fit):
TAX_BRACKET_MANAGEMENT — default for most staged conversions where the main concern is staying within favorable brackets.
LIQUIDITY_CONSTRAINT — when the conversion period is long or the client has liquidity concerns.
RMD_NEAR_TERM — when the reason to defer is unfavorable RMD timing (e.g., conversion would start after RMDs have already begun and the analysis recommends no conversion).
Output Format
- Return only a single JSON object. No markdown fences, no explanatory prose outside the JSON.
- Required top-level keys (order does not matter):
task_id, client_id, analysis_type, recommendation, conversion_plan, rmd_projection, legacy_projection, source_resolution
task_id: use the task identifier supplied by the harness (e.g., train_001, test_001).
client_id: from the memo.
analysis_type: always "roth_conversion_rmd".
- All monetary values must be JSON numbers (not strings), rounded to exactly two decimal places (cents).
- All years must be JSON integer numbers.
- Enum strings must match the template exactly (all caps with underscores).
Calculation Checks
annual_conversion_amount × conversion_years should equal total_converted (within rounding).
baseline_rmd_tax_through_horizon - conversion_rmd_tax_through_horizon should equal rmd_tax_savings_through_horizon (within rounding).
- In a no-conversion case:
total_converted = 0
total_conversion_tax = 0
rmd_tax_savings_through_horizon = 0
baseline_rmd_tax_through_horizon should equal conversion_rmd_tax_through_horizon
annual_conversion_amount = 0
- Ensure
conversion_years_positive is consistent with the sign of annual_conversion_amount.
Pitfalls
- Conflicting sources: Never blindly use the first record returned. Always apply the source-resolution hierarchy.
- Numeric types: Outputting
"1234.56" (a string) instead of 1234.56 (a number) will fail validation.
- Horizon year: It comes from the memo, not from a hard-coded default.
- RMD age rules: Use the API’s tax-policy constants if available; do not hard-code outdated RMD ages.
- No-conversion edge case: Even when the recommendation is
NO_CONVERSION, the conversion_plan object may still contain a first_conversion_year and conversion_years describing the theoretical window, but all monetary fields must be zero.
- One-cent rounding drift: When summing year-by-year taxes, carry cents each year or round only the final total; if you round every year independently, a 1-cent discrepancy in
rmd_tax_savings_through_horizon is possible and acceptable.
1---2name: fewshot-attempt-02-223description: Skill: Roth Conversion RMD Analysis for Wealth Advisory4---5# Skill: Roth Conversion RMD Analysis for Wealth Advisory67## Overview8Generate a structured JSON comparison of Roth conversion versus RMD baseline for a private-wealth advisory client. The procedure queries an advisory API, resolves conflicting multi-source records, projects taxes and balances through a planning-horizon year, and produces a recommendation.910## API Usage111. Obtain the advisory API base URL from the environment (commonly exposed as `API_BASE` after the shared environment starts).122. Query all relevant endpoints for the given `client_id`:13 - Client profile and demographics14 - Account holdings and custodian exports15 - Tax-policy constants (brackets, rates, thresholds)16 - RMD factors / uniform lifetime table17 - Any source documents, life-insurance records, or trust candidates183. Conflicts are expected because records were imported from different systems. Keep every source value and its provenance tag for resolution.1920## Source Resolution Rules21Apply these hierarchies **before** using any data in calculations.2223- **Profile / demographic data** (highest priority first):24 1. `SIGNED_PROFILE`25 2. `ATTORNEY_MEMO`26 3. `CUSTODIAN_EXPORT`27 4. `CRM_NOTE`28 5. `STALE_MARKETING_INTAKE`29- **Account / balance data** (highest priority first):30 1. `CUSTODIAN_EXPORT`31 2. `SIGNED_PROFILE`32 3. `CRM_NOTE`3334Report the winning source tags in:35- `source_resolution.controlling_profile_source`36- `source_resolution.controlling_account_source`3738## Analysis Steps3940### 1. Anchor dates and horizon41- `client_id` and the **planning horizon year** come from the advisor request memo.42- Determine the client’s birth year / age from the resolved profile.43- Compute the **first RMD year** using the resolved tax-policy constants (e.g., SECURE 2.0 rules: age 73 for birth years 1951–1959, age 75 for 1960+).4445### 2. Baseline scenario (no conversion)46- Project the resolved traditional retirement-account balance forward year by year through the horizon.47- Starting in the first RMD year, apply the applicable RMD factor each year to determine the required distribution.48- Tax each distribution using the resolved ordinary-income brackets.49- Accumulate the taxes → `baseline_rmd_tax_through_horizon`.5051### 3. Conversion scenario52- If the memo explicitly states **"no conversion is requested"** (or the client is clearly unsuitable), set all conversion amounts to `0` and skip to step 5, but still keep any baseline plan years in `conversion_plan` with zeroed amounts.53- Otherwise, build a **staged conversion plan**:54 - `first_conversion_year` is normally the current / next year.55 - `conversion_years` is the count of years over which conversions are spread.56 - `conversion_years_positive` equals `conversion_years` when conversion is positive; in no-conversion cases it may match the planned window but amounts must be `0`.57 - `annual_conversion_amount` = `total_converted / conversion_years`, rounded to cents.58 - `total_conversion_tax` = sum of tax on each year’s converted amount, rounded to cents.59- After removing converted amounts, reproject the remaining traditional balance and its yearly RMDs.60- Accumulate post-conversion RMD taxes → `conversion_rmd_tax_through_horizon`.6162### 4. Savings and legacy projection63- `rmd_tax_savings_through_horizon` = `baseline_rmd_tax_through_horizon - conversion_rmd_tax_through_horizon`.64 - Allow a one-cent tolerance because intermediate year-by-year rounding can propagate.65- Project the Roth balance at horizon by growing the converted amounts.66- Project the remaining traditional balance at horizon.67- Set `heir_tax_profile`:68 - `MOSTLY_TAXABLE` when the Roth balance is negligible (e.g., no conversion occurred).69 - `MIXED_TAXABLE_AND_TAX_FREE` when both Roth and traditional balances are materially positive.70 - `MOSTLY_TAX_FREE` when the traditional balance is negligible.7172### 5. Recommendation73- `primary_action`:74 - `NO_CONVERSION` when the memo explicitly says no conversion is requested, or when analysis shows conversion is unsuitable.75 - `STAGED_ROTH_CONVERSION` otherwise.76- `suitability`:77 - `SUITABLE` for staged conversions.78 - `DEFER` for no-conversion recommendations.79- `risk_flag` (choose the best fit):80 - `TAX_BRACKET_MANAGEMENT` — default for most staged conversions where the main concern is staying within favorable brackets.81 - `LIQUIDITY_CONSTRAINT` — when the conversion period is long or the client has liquidity concerns.82 - `RMD_NEAR_TERM` — when the reason to defer is unfavorable RMD timing (e.g., conversion would start after RMDs have already begun and the analysis recommends no conversion).8384## Output Format85- Return **only** a single JSON object. No markdown fences, no explanatory prose outside the JSON.86- Required top-level keys (order does not matter):87 - `task_id`, `client_id`, `analysis_type`, `recommendation`, `conversion_plan`, `rmd_projection`, `legacy_projection`, `source_resolution`88- `task_id`: use the task identifier supplied by the harness (e.g., `train_001`, `test_001`).89- `client_id`: from the memo.90- `analysis_type`: always `"roth_conversion_rmd"`.91- All monetary values must be JSON **numbers** (not strings), rounded to exactly two decimal places (cents).92- All years must be JSON integer numbers.93- Enum strings must match the template exactly (all caps with underscores).9495## Calculation Checks96- `annual_conversion_amount × conversion_years` should equal `total_converted` (within rounding).97- `baseline_rmd_tax_through_horizon - conversion_rmd_tax_through_horizon` should equal `rmd_tax_savings_through_horizon` (within rounding).98- In a no-conversion case:99 - `total_converted = 0`100 - `total_conversion_tax = 0`101 - `rmd_tax_savings_through_horizon = 0`102 - `baseline_rmd_tax_through_horizon` should equal `conversion_rmd_tax_through_horizon`103 - `annual_conversion_amount = 0`104- Ensure `conversion_years_positive` is consistent with the sign of `annual_conversion_amount`.105106## Pitfalls107- **Conflicting sources:** Never blindly use the first record returned. Always apply the source-resolution hierarchy.108- **Numeric types:** Outputting `"1234.56"` (a string) instead of `1234.56` (a number) will fail validation.109- **Horizon year:** It comes from the memo, not from a hard-coded default.110- **RMD age rules:** Use the API’s tax-policy constants if available; do not hard-code outdated RMD ages.111- **No-conversion edge case:** Even when the recommendation is `NO_CONVERSION`, the `conversion_plan` object may still contain a `first_conversion_year` and `conversion_years` describing the theoretical window, but all monetary fields must be zero.112- **One-cent rounding drift:** When summing year-by-year taxes, carry cents each year or round only the final total; if you round every year independently, a 1-cent discrepancy in `rmd_tax_savings_through_horizon` is possible and acceptable.