Work / Chitragupt / Wiki / Concepts
tax-recompute-engine
Conceptcanonicalverified 2026-07-12
CONCEPT.TAX-RECOMPUTE-ENGINESummary
The tax recompute engine is a single-pass, both-regime, statute-driven
pipeline that turns confirmed ledger entries into the persisted
tax_reviews/{ay} document read by the Tax Review pages.
Why it matters
Every tax number a user sees — the four-state hero
(refund / owe / clear / incomplete), the recommended regime, the
composition donut, the 15-Q Quick Check state — traces back to one
call to runMode1ForAY in packages/shared/src/rules/v1/orchestrator.ts.
When the engine is wrong, every user sees the same wrong tax; when
it's right, staleness is bounded by the drain scheduler
(user-identity-entry).
The July 2026 audit closed 30+ statute-correctness bugs across the tax pillar. Documenting the engine's shape here so subsequent audits can find and fix new bugs without re-deriving the pipeline.
Implications
- AY tables are the single source of truth for statute values.
Slab rates, §87A rebate, surcharge bands, cess, capital-gains
sub-rules, §80CCD(2) caps, §71 loss-set-off cap, §80G donee-driven
math, regime-recommendation thresholds, NRI basic exemption — all
cells live in
packages/shared/src/data/tax-tables/ay-*.ts. Zero statute values may be hardcoded in engine code. - Both regimes compute in one pass; recommendation picks the winner.
runMode1ForAYcallscomputeTaxtwice (old / new) with the same inputs; the recommendation is the cheaper one. Therecommendation_reasonstring is table-thresholded (see 2026-07-12-real-80g-donee-category-math for the pattern). - Position credits = TDS + advance-tax + self-assessment challans.
The pre-Phase-2 engine only credited TDS. Challan credits come from
the
advance_tax_challan+self_assessment_challanledger buckets. - §234A/B/C interest is stamped on Position. See 2026-07-12-234abc-interest-and-hra-min-of-three.
- HRA is validated by min-of-three, not taken verbatim from Form 16. Same ADR.
- Debt-MF gains route through their own tax buckets. See 2026-07-12-debt-mf-treated-independently-of-equity-cg.
- Ledger AY comes from the transaction date, not the document. See 2026-07-12-per-txn-ay-bucketing-for-expense-ledger.
- Position dedup on portfolio side. See 2026-07-12-portfolio-position-dedup.
Pipeline (per-AY)
summariseIncome— aggregates ledger entries by bucket (salary / rental / CG / VDA / §80C / §80D / §80CCD(2) / §24(b) self+let-out / HRA inputs / advance-tax / etc.).applySalarySlipFallback— if no Form 16 for the AY but slips exist, annualises by distinct-month count fromtxn_date.applyHraValidation— overrides Form-16 HRA with §10(13A) min-of-three when basic salary + rent paid are known.capsFromTable— per-section Chapter VI-A caps (age-aware).chapterVIABreakdown— applies caps + §80G donee math + §80C aggregate with §80CCC + §80CCD(1).computeTax(regime: "old")+computeTax(regime: "new")— each applies standard deduction, §24(b) split (self-occupied vs let-out with regime-specific rules), §71 HP-loss cap, §80CCD(2) employer NPS, slab tax with NRI awareness, §111A/§112A equity CG, debt-MF split CG, §115BBH VDA, §87A rebate (with total-income ceiling that includes VDA + debt-MF), surcharge with marginal relief, cess.- Position, composition, TDS reconciliation, per-Q quick_check.
computeInterest234ForReview— §234A/B/C on the recommended tax.- Return
TaxReview. Persister writes to Firestore.
Related
- pillar-tax — the surface this feeds.
- user-identity-entry — the ledger shape the engine consumes.
- categorise-assist — user re-categorisation triggers the drain scheduler which re-runs this pipeline.
- ADRs referenced above.
Sources
packages/shared/src/rules/v1/orchestrator.ts— the entry point.packages/shared/src/rules/v1/tax-computer.ts— the per-regime compute.packages/shared/src/rules/v1/income-summary.ts— the aggregator.packages/shared/src/rules/v1/hra-exemption.ts— §10(13A) min-of-three.packages/shared/src/rules/v1/interest-234.ts— §234A/B/C.packages/shared/src/data/tax-tables/schema.ts+ay-*.ts— the statute cell store.
Every project of mine is written down like this.
Read the résumé