// fica-payroll-tax.cjs -- METHOD DECK (X063). // Per the Founder rule via W001/PQ021, any value that changes over time is an input with a // source and a date. The Social Security wage base is indexed every year, and even the // statutory rates and Additional Medicare Tax thresholds could be changed by future legislation, // so all six FICA table values (the wage base, the three rates, and the two thresholds) are now // typed inputs rather than baked constants, each prefilled with the currently cited 2026 value. // They move together as one dated table, so they share one fica_table_source and one // fica_table_date companion input rather than six separate citations. module.exports = { slug: "fica-payroll-tax", title: "FICA payroll tax, by stated table", deck_category: "tax", description: "Computes employee-side FICA tax (Social Security, Medicare, and Additional Medicare Tax) on a given amount of annual wages, using a stated, cited FICA table.", inputs: [ { name: "annual_wages", type: "number", unit: "currency units", required: true, description: "Total annual wages subject to FICA", min: 0 }, { name: "filing_status", type: "string", required: true, description: "Filing status, used only for the Additional Medicare Tax threshold", enum: ["single", "married_filing_jointly", "head_of_household"] }, { name: "social_security_wage_base", type: "number", unit: "currency units", required: true, description: "The Social Security (OASDI) taxable wage base for the year being computed; indexed annually by the SSA.", min: 0 }, { name: "social_security_rate_percent", type: "number", unit: "%", required: true, description: "Employee-side Social Security tax rate.", min: 0 }, { name: "medicare_rate_percent", type: "number", unit: "%", required: true, description: "Employee-side Medicare tax rate, applied to all wages with no cap.", min: 0 }, { name: "additional_medicare_rate_percent", type: "number", unit: "%", required: true, description: "Additional Medicare Tax rate on wages above the filing-status threshold.", min: 0 }, { name: "additional_medicare_threshold_mfj", type: "number", unit: "currency units", required: true, description: "Additional Medicare Tax threshold for married filing jointly.", min: 0 }, { name: "additional_medicare_threshold_other", type: "number", unit: "currency units", required: true, description: "Additional Medicare Tax threshold for single or head of household.", min: 0 }, { name: "fica_table_source", type: "string", required: true, description: "Citation for the wage base, rates, and thresholds above; change it together with all six values when using a newer year's table." }, { name: "fica_table_date", type: "string", unit: "ISO date", required: true, description: "The date the cited FICA table was retrieved or published." } ], outputs: [ { name: "social_security_tax", unit: "currency units", description: "social_security_rate_percent of wages up to social_security_wage_base" }, { name: "medicare_tax", unit: "currency units", description: "medicare_rate_percent of all wages" }, { name: "additional_medicare_tax", unit: "currency units", description: "additional_medicare_rate_percent of wages above the filing-status threshold" }, { name: "total_fica_tax", unit: "currency units", description: "Sum of the three components" } ], steps: [ "The visitor supplies social_security_wage_base, social_security_rate_percent, medicare_rate_percent, additional_medicare_rate_percent, both Additional Medicare Tax thresholds, plus fica_table_source and fica_table_date; this method never looks up a table itself. Replace all eight together to use a newer official table.", "social_security_tax = social_security_rate_percent / 100 * min(annual_wages, social_security_wage_base).", "medicare_tax = medicare_rate_percent / 100 * annual_wages (no wage base cap).", "additional_medicare_tax = additional_medicare_rate_percent / 100 * max(0, annual_wages - threshold), where threshold is additional_medicare_threshold_mfj for married filing jointly, otherwise additional_medicare_threshold_other.", "total_fica_tax = social_security_tax + medicare_tax + additional_medicare_tax.", "Round every component to 2 decimals (money to cents)." ], constants: [ { name: "social_security_wage_base_2026", value: 184500, unit: "currency units", source: 0 }, { name: "social_security_rate", value: 0.062, unit: "rate", source: 0 }, { name: "medicare_rate", value: 0.0145, unit: "rate", source: 1 }, { name: "additional_medicare_rate", value: 0.009, unit: "rate", source: 1 }, { name: "additional_medicare_threshold_mfj", value: 250000, unit: "currency units", source: 1 }, { name: "additional_medicare_threshold_other", value: 200000, unit: "currency units", source: 1 } ], sources: [ { kind: "url", value: "https://www.ssa.gov/oact/cola/cbb.html", title: "Contribution and Benefit Base (2026 Social Security taxable maximum: $184,500)", publisher: "Social Security Administration", retrieved_utc: "2026-09-30T19:31:29Z", note: "SSA's official 2026 OASDI wage base, announced with the October 2025 COLA determination; documented source of the social_security_wage_base default value." }, { kind: "url", value: "https://www.irs.gov/taxtopics/tc560", title: "Topic no. 560, Additional Medicare Tax", publisher: "Internal Revenue Service", retrieved_utc: "2026-09-30T19:31:29Z", note: "Medicare tax rate 1.45% with no wage cap; Additional Medicare Tax of 0.9% above statutory (not inflation-adjusted) thresholds of $250,000 MFJ / $200,000 single or head of household; documented source of the rate and threshold default values." } ], disclaimer: "General payroll tax formula only, using a stated, cited FICA table. Not tax advice. Employer-side matching and self-employment tax rules differ. Consult a licensed tax professional or the IRS/SSA for your actual situation.", questionText(inputs) { const statusText = { single: "single", married_filing_jointly: "married filing jointly", head_of_household: "head of household" }[inputs.filing_status]; return `Using the FICA table from ${inputs.fica_table_source} (dated ${inputs.fica_table_date}), what is the FICA tax (Social Security, Medicare, and Additional Medicare Tax) on $${inputs.annual_wages} of annual wages for a ${statusText} filer?`; }, run(inputs) { const { annual_wages, filing_status, social_security_wage_base, social_security_rate_percent, medicare_rate_percent, additional_medicare_rate_percent, additional_medicare_threshold_mfj, additional_medicare_threshold_other, fica_table_source, fica_table_date } = inputs; if (typeof annual_wages !== "number" || annual_wages < 0) throw new Error("annual_wages must be a non-negative number"); if (!["single", "married_filing_jointly", "head_of_household"].includes(filing_status)) throw new Error("filing_status must be one of: single, married_filing_jointly, head_of_household"); for (const [k, v] of [ ["social_security_wage_base", social_security_wage_base], ["social_security_rate_percent", social_security_rate_percent], ["medicare_rate_percent", medicare_rate_percent], ["additional_medicare_rate_percent", additional_medicare_rate_percent], ["additional_medicare_threshold_mfj", additional_medicare_threshold_mfj], ["additional_medicare_threshold_other", additional_medicare_threshold_other] ]) { if (typeof v !== "number" || !isFinite(v) || v < 0) throw new Error(k + " must be a non-negative number"); } if (typeof fica_table_source !== "string" || !fica_table_source.trim()) throw new Error("fica_table_source must be a non-empty string"); if (typeof fica_table_date !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(fica_table_date)) throw new Error("fica_table_date must be a string in YYYY-MM-DD format"); const threshold = filing_status === "married_filing_jointly" ? additional_medicare_threshold_mfj : additional_medicare_threshold_other; const social_security_tax = Math.round((social_security_rate_percent / 100) * Math.min(annual_wages, social_security_wage_base) * 100) / 100; const medicare_tax = Math.round((medicare_rate_percent / 100) * annual_wages * 100) / 100; const additional_medicare_tax = Math.round((additional_medicare_rate_percent / 100) * Math.max(0, annual_wages - threshold) * 100) / 100; const total_fica_tax = Math.round((social_security_tax + medicare_tax + additional_medicare_tax) * 100) / 100; const fmt = (n) => n.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ","); return { answer: `$${fmt(total_fica_tax)}`, values: { social_security_tax, medicare_tax, additional_medicare_tax, total_fica_tax } }; }, examples: [ { name: "worked example", inputs: { annual_wages: 150000, filing_status: "single", social_security_wage_base: 184500, social_security_rate_percent: 6.2, medicare_rate_percent: 1.45, additional_medicare_rate_percent: 0.9, additional_medicare_threshold_mfj: 250000, additional_medicare_threshold_other: 200000, fica_table_source: "SSA Contribution and Benefit Base (2026) and IRS Topic 560", fica_table_date: "2026-09-30" }, expected: { answer: "$11,475.00" }, check: "hand computation: SS = 0.062*150000 = 9300.00 (under wage base); Medicare = 0.0145*150000 = 2175.00; Additional Medicare = 0 (under 200000 threshold); total = 9300+2175+0 = 11475.00" }, { name: "test vector: wages above both the wage base and the Additional Medicare threshold", inputs: { annual_wages: 300000, filing_status: "married_filing_jointly", social_security_wage_base: 184500, social_security_rate_percent: 6.2, medicare_rate_percent: 1.45, additional_medicare_rate_percent: 0.9, additional_medicare_threshold_mfj: 250000, additional_medicare_threshold_other: 200000, fica_table_source: "SSA Contribution and Benefit Base (2026) and IRS Topic 560", fica_table_date: "2026-09-30" }, expected: { answer: "$16,239.00" }, check: "hand computation: SS = 0.062*184500 = 11439.00 (capped at wage base); Medicare = 0.0145*300000 = 4350.00; Additional Medicare = 0.009*(300000-250000) = 0.009*50000 = 450.00; total = 11439+4350+450 = 16239.00" } ] };