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
- Show a figure for a profile no dataset covers.
- Present demo data without the banner, or with a grade above INSUFFICIENT.
- Apply a location, industry, company or skill differential without a dataset behind it.
- Promote a newer but weaker figure over a better-graded one.
- Make a salary recommendation on LOW or INSUFFICIENT evidence.
- Store or transmit a profile.
13. Known limits, today
- Role-level verified coverage is newly qualified Chartered Accountants at national level (three ICAI placement seasons, as reported), plus the PLFS all-occupation benchmark. Other roles and bands are INSUFFICIENT.
- The location differential is state-level and all-occupation (PLFS 2023-24); the 2025 state tables are queued.
- No verified industry level differential, company-type factor or skill premium exists yet.
- ICAI's own announcements should be archived per season to replace the press reports.
Sources, raw extracts and versions: the data catalogue.