CA. Akhilesh Kumarcaakhilesh.in

Methodology

The rules the engine follows, in the order it follows them, and the things it will not do. Engine v2, data layer v2, last verified 2026-09-15.

1. The data layer

Four kinds of file live in career-data/. Raw extracts are verbatim transcriptions from the source documents with page references; they are never edited. Normalised observations map a raw figure to the taxonomies (role, experience band, geography, industry) with its source, URL, collection and effective dates, sample, methodology, confidence, limitations and a provenance reference into the raw file. Adjustment datasets (location, wage growth, industry growth) carry the same fields. Historical files are superseded versions kept byte-for-byte and checksummed. A manifest, versions.json, lists every dataset with its status, review date and checksum.

At build the loader validates every row: an unknown role or source, a non-https URL, a malformed date, a confidence outside 0–1, a verified row without a last-verified date or a provenance reference, a normalised value that does not equal its raw figure (monthly × 12, lakh × 10⁵ or as printed), a changed historical file — any of these fails the build. Nothing that fails reaches the page.

1a. Five evidence dimensions, never combined

Every role carries five independent layers, each with its own state, source, date, freshness, confidence and provenance. Salary — role-level pay observations; VERIFIED, LIMITED or INSUFFICIENT. Market demand — the year-on-year change in job postings for the sector the role's function maps to (Naukri JobSpeak); SIGNAL or none. Skill signals — the skills the taxonomy marks as core to the function, each shown with the posting change of the sector it sits in; a sector signal beside a skill, never a measurement of the skill itself and never a premium. Location — the PLFS state differential, all occupations, LIMITED by design. Industry — Aon's projected increase, a growth signal with a level factor of 1.00. A demand or skill signal is never turned into a salary figure: a role with salary INSUFFICIENT shows "Salary evidence insufficient" and its demand and skill intelligence, nothing more.

2. Normalisation of your profile

Free text is matched to the taxonomies by name and alias, longest match wins. A "Chartered Accountant" with under two years is mapped to the newly-qualified CA role, because that is what the placement data measures. A city inherits its state for the location differential. Unknown locations and industries fall to "other" or national, never to a guessed city. Nothing you enter is stored or sent.

3. Matching and widening

Observations are searched at three tightnesses: exact (role, band, geography, industry); national across all industries; the same role in a neighbouring band. Each widening is written into the limitations and costs confidence (−0.10, −0.30). Verified datasets are searched before demo data, and demo data only when you switch it on.

4. Evidence grade — HIGH / MEDIUM / LOW / INSUFFICIENT

Deterministic, per observation: start from the observation's confidence, subtract the widening penalty, add 0.10 if a distribution (p25/p50/p75) exists; HIGH at 0.65 or more, MEDIUM at 0.45, LOW above 0. Then three caps: figures that reach the layer through a press report of a primary announcement are capped at MEDIUM; an observation older than 18 months (ageing) is capped at MEDIUM; older than 30 months (stale) is capped at LOW. Demo data is INSUFFICIENT whatever the arithmetic. No observation at all is INSUFFICIENT.

The headline figure is the best-graded observation for the profile, ties going to the newest. A newer figure from a weaker source is shown in the series and named in the limitations, not promoted to the headline.

Employer-published pay — a recruitment advertisement or hiring page (SBI, TCS) — is a fourth kind of evidence. It is what one employer pays one cadre, so it is capped at MEDIUM, never widened to a neighbouring band, never location-adjusted, and never blended with a benchmark: the result says employer-published, names the employer and cadre, and lists the other cadre figures from the same source as context.

5. Adjustments

Location. The state's average monthly earnings of urban regular wage/salaried employees (PLFS 2023-24, Table 38, Apr–Jun 2024, person) divided by the all-India urban figure (₹24,434). It is a general wage-level differential for the state, not a city salary index and not specific to any profession; the page says so wherever it is applied. Industry. No verified level differential exists, so the factor is 1.00; Aon's projected 2026 increase for the industry is shown as a growth signal. Company type and skills. No verified dataset; factor 1.00 (demo factors only when demo is on, graded INSUFFICIENT).

6. Indexing older observations

When the headline observation is six months old or more, a separate indexed line compounds it at a published growth rate (default: Aon's projected 2026 increase of 9.1%) for the elapsed time. It is graded LOW and labelled an assumption: it presumes the role moved with the average, which it may not have. It never replaces the headline.

7. Position and gap

With a distribution, the percentile is interpolated linearly through p25, p50 and p75 (extrapolated gently outside, capped at p1 and p99). With only a mean and a maximum — the ICAI placement data — no percentile is stated; the position is described against the average and the highest offer. The gap is median (or mean) minus current total pay.

8. Confidence score and recommendations

The 0–100 score is 60% the headline's confidence, 25% the mean confidence of the adjustment layers, 15% for a distribution (5% for summary statistics). Recommendations are gated by grade: only HIGH or MEDIUM evidence may say you are paid below or above market; LOW evidence says the data is too thin or old to judge; INSUFFICIENT makes no salary recommendation at all. Every sentence exists in the engine's source; nothing is generated.

9. Provenance

Every result prints its chain: dataset and version → observation (id, source, dates, raw file and reference) → normalisation (the ids your profile became) → calculation (each factor and the combined factor) → result. The same chain is what the tests check.

10. Freshness and updates

Each dataset has a review date; each observation is dated and flagged fresh, ageing or stale relative to the build date. Replacing a dataset means adding a new file and version row, moving the old one to historical/ with its checksum, and rebuilding — the engine reads whatever the manifest registers, so no engine change is needed. The build reports datasets due for review.

11. Learning from outcomes, later

No model is trained from what readers type, and nothing is recorded today. The engine raises a browser event carrying ids only (role, band, grade, status) so that a future, opt-in feature could collect anonymised outcomes in the shape described in career-data/events/schema.json — coarse pay bands, never exact figures, never names, employers or identifiers. Any dataset built from such events would pass the same validator and review as any other before it is registered.

12. What it refuses to do

13. Known limits, today

Sources, raw extracts and versions: the data catalogue.