What every level of Indian education is worth
Aggregate analysis of public government survey microdata (MoSPI PLFS). No Avanti student data and no personally identifiable information: every figure is a weighted population share or a cell count.
PLFS CY2025. 263,446 people surveyed, representing 265.2 million aged 21–34 — a lower bound, since PLFS weights are anchored to Census 2011 and run 15–25% below true population. Shares are unaffected. Eleven rungs, from below-middle-school to postgraduate. August 2026.
Of every hundred Indians aged 21–34, fewer than ten hold a formal job — regular salaried work with a contract or social security. Which rung of the education ladder they are on changes that number by a factor of thirty-two.
But the ladder is not a ladder. A technical diploma beats a general degree — comfortably, and it is the one comparison here that is statistically unambiguous. A postgraduate degree does not measurably out-employ that diploma. And below middle school, twenty years of working life add 6% to the mean wage.
Postgraduates are split by field, and that split changed a finding. Left as one bucket the rung reads 29.11%; split, it runs from 25.57% for a general master’s to 62.12% for a medical one — the highest rate on the whole ladder. “More education does not help” was really “a general master’s does not help”.
Each rung has its own self-contained note in rungs/. This page is the comparison.
Provenance. ASSUMPTIONS.md numbers every assumption, what it would change if
wrong, and whether it was tested. QUERIES.md gives the exact SQL behind every number,
including the seven verification queries that changed a conclusion. FINDINGS.md
grades every claim solid / directional / retracted — seven claims were retracted on review and
are listed there so they are not reintroduced.
The ladder
Section titled “The ladder”| Rung | Population | Regular salaried | Formal work | — people | Informal wage | Self-emp | Studying | Unemployed | Domestic duties |
|---|---|---|---|---|---|---|---|---|---|
| 01. Below middle school | 53.97m | 9.08% | 1.66% | 898k | 31.34% | 15.55% | 0.01% | 0.50% | 35.25% |
| 02. Middle school | 50.82m | 13.90% | 3.57% | 1.81m | 29.55% | 16.41% | 0.07% | 1.20% | 33.01% |
| 03. Secondary (10th) | 34.03m | 17.75% | 5.95% | 2.02m | 24.96% | 16.94% | 0.78% | 1.98% | 34.46% |
| 04. Higher secondary (12th) | 47.85m | 17.06% | 7.38% | 3.53m | 16.23% | 13.70% | 14.97% | 3.59% | 28.36% |
| 05. Diploma, technical | 4.06m | 46.18% | 30.77% | 1.25m | 18.98% | 13.43% | 7.76% | 8.30% | 9.72% |
| 06. Diploma, non-technical | 2.85m | 40.74% | 25.80% | 735k | 20.29% | 14.23% | 6.89% | 8.57% | 13.34% |
| 07. Degree, engineering | 5.42m | 56.92% | 52.58% | 2.85m | 4.29% | 7.84% | 6.05% | 15.46% | 7.79% |
| 08. Degree, medical | 0.85m | 45.67% | 32.41% | 275k | 12.67% | 10.80% | 18.82% | 8.51% | 10.52% |
| 09. Degree, other technical | 2.27m | 33.55% | 24.85% | 565k | 8.17% | 8.32% | 13.02% | 17.87% | 16.24% |
| 10. Degree, general | 49.26m | 24.91% | 16.20% | 7.98m | 9.84% | 10.76% | 11.83% | 11.75% | 24.96% |
| 11. Postgraduate, general | 11.15m | 34.26% | 25.57% | 2.85m | 8.28% | 9.42% | 6.51% | 14.59% | 24.87% |
| 12. Postgraduate, other technical | 1.64m | 47.30% | 37.26% | 612k | 8.54% | 7.29% | 4.26% | 19.70% | 16.20% |
| 13. Postgraduate, engineering | 0.81m | 59.33% | 53.13% | 432k | 5.74% | 6.77% | 4.89% | 10.89% | 14.36% |
| 14. Postgraduate, medical | 0.20m | 67.50% | 62.12% | 124k | 5.11% | 10.25% | 4.96% | 9.37% | 6.63% |
Rows sum to under 100. What sits outside: unpaid family workers (pas='21', 9.6% at rung 01),
self-employed reporting no positive earnings, rentiers, and those unable to work. Casual wage labour
is inside the informal-wage column, not outside it — at rung 01 it is 24.2 of that column’s 31.3
points, so “informal wage work” there means daily-wage labour rather than informal salaried work.
The same rungs at the fresh-graduate window
Section titled “The same rungs at the fresh-graduate window”The table above is the whole 21–34 stock: it mixes a graduate three months out of college with one
twelve years into a career. extract.sql also emits every rung read only in the first three years
after that course normally finishes — section='activity_fresh'. That is the window a placement
brochure is describing, and the only one comparable to a college’s published placement figure.
The rule is the house rule from ../plfs/entry/:
engineering 22–24, MBBS 24–26, three-year degrees and diplomas 21–23. Engineering reproduces that
analysis exactly (n=1,042, 1.16m people, 34.65% formal), which is the check that the window was
carried over rather than reinvented. Two extensions are flagged in the SQL and on the view:
postgraduate rungs add two years to the underlying degree, and school rungs are held at 21–23 as a
same-age floor rather than a fresh-graduate outcome.
| At its own window | People | Formal work, fresh | Formal work, 21–34 | Unemployment rate |
|---|---|---|---|---|
| Below middle school | 7.18m | 0.84% | 1.66% | 1.71% |
| Higher secondary (12th) | 16.01m | 3.48% | 7.38% | 12.22% |
| Diploma, technical | 1.05m | 21.18% | 30.77% | 19.73% |
| Degree, engineering | 1.16m | 34.65% | 52.58% | 41.56% |
| Degree, other technical | 0.49m | 10.86% | 24.85% | 50.97% |
| Degree, general | 13.10m | 7.18% | 16.20% | 34.35% |
| Postgraduate, engineering | 0.17m | 42.88% | 53.13% | 25.43% |
Unemployment here is pct_unemployed_of_lf — seeking work over the labour force, not over the whole
rung, which is the only version comparable to a national unemployment rate. Two readings:
Most of the degree’s advantage has not arrived yet. Engineering ends at 52.58% formal and starts at 34.65%. Two thirds of the eventual advantage is missing at the point a placement figure is quoted.
The queue is a graduate phenomenon, and it inverts the ladder. 1.71% unemployment below middle school against 41.56% for a fresh engineering graduate and 50.97% for other technical degrees. Someone who left school early is almost never unemployed — 30.05% of that rung is in informal wage work, because they take whatever exists. The graduate holds out for the job the degree promised.
All of it, as one page: The fresh-graduate window
— public, no sign-in. Source: output/fresh-graduates.html, rebuilt
by build_fresh_graduates_view.py. Re-upload after any rebuild:
gcloud storage cp --content-type=text/html output/fresh-graduates.html \ gs://avantifellows-bq-assistant/analysis/plfs-education-ladder/fresh-graduates.htmlpython3 ../../scripts/check_published_views.py # fails if the two have driftedForgetting the upload is the failure this analysis is most exposed to — a stale public page renders
perfectly, with old numbers, at a URL three READMEs point to. The check above is wired into CI on
every PR, every push to main, and weekly.
What each rung actually does
Section titled “What each rung actually does”Job function among those in formal work, from the committed NCO map in
build_job_function.py. NCO orders occupations by skill level before
function, so software work is scattered across 251/252 (professionals), 351/352 (technicians) and
133 (managers); a raw occupation table splits one job three ways. Full tables are in each rung note.
| Rung | The three largest functions |
|---|---|
| 01. Below middle school | Skilled trades & production 44% · Hospitality, personal & care services 21% · Agriculture, forestry & fishing 15% |
| 02. Middle school | Skilled trades & production 46% · Hospitality, personal & care services 16% · Transport & logistics 15% |
| 03. Secondary (10th) | Skilled trades & production 46% · Hospitality, personal & care services 11% · Transport & logistics 11% |
| 04. Higher secondary (12th) | Skilled trades & production 27% · Clerical & office support 14% · Sales & marketing 14% |
| 05. Diploma, technical | Skilled trades & production 33% · Engineering, science & technical 21% · Health & medical 15% |
| 06. Diploma, non-technical | Skilled trades & production 38% · Engineering, science & technical 11% · Health & medical 10% |
| 07. Degree, engineering | Software & IT 52% · Engineering, science & technical 21% · Clerical & office support 6% |
| 08. Degree, medical | Health & medical 76% · Sales & marketing 7% · Clerical & office support 4% |
| 09. Degree, other technical | Teaching & education 25% · Software & IT 20% · Clerical & office support 14% |
| 10. Degree, general | Clerical & office support 19% · Sales & marketing 15% · Finance & accounting 11% |
| 11. Postgraduate, general | Teaching & education 23% · Clerical & office support 17% · Software & IT 12% |
| 12. Postgraduate, other technical | Teaching & education 36% · Sales & marketing 14% · Management & business operations 12% |
| 13. Postgraduate, engineering | Software & IT 45% · Management & business operations 18% · Engineering, science & technical 15% |
| 14. Postgraduate, medical | Health & medical 80% · Teaching & education 10% · Engineering, science & technical 6% |
Three readings.
- An engineering degree is a software qualification. 51.6% of employed engineering graduates do Software & IT work against 21.3% doing engineering, science or technical work. The same holds for the master’s — 45.2% software. Whatever the degree is called, the destination is software.
- Medicine is the only field whose degree names its job. 76.1% of employed medical graduates work in health, and 79.6% of postgraduates. No other rung reaches even 52% concentration.
- A general degree has no characteristic destination. Its largest function is Clerical & office support at 18.9%, and the top three cover barely half. Compare the school rungs, which are coherently manual — 44–46% skilled trades — and the technical diploma, which is genuinely technical at 21.4% engineering plus 15.1% health.
Four things this shows
Section titled “Four things this shows”1. The biggest step is the diploma, not the degree
Section titled “1. The biggest step is the diploma, not the degree”Higher secondary reaches 7.38% formal employment. A technical diploma reaches 30.77% — more than four times.
“On top of it” is the wrong phrase, and the data cannot fix it. Most Indian polytechnic diplomas
follow class 10, not class 12, and PLFS gives no way to tell the two entry routes apart —
no_of_years_in_formal_education is entirely NULL in this release. So the diploma is not
straightforwardly the rung above higher secondary; for many holders the right comparison is
secondary’s 5.95%, which makes the step larger, not smaller. Either way it is the largest gap
between any two rungs on this ladder. See ASSUMPTIONS.md G2.
Compare that with the degree route. Higher secondary to a general degree is 7.38% → 16.20%, barely double, for three or four years of study.
And most of what the diploma buys is not the technical content. A non-technical diploma still delivers 25.80%.
The technical premium on top of that is entirely an engineering effect: engineering diplomas reach 33.41%, while diplomas in agriculture, medicine and crafts reach 22.51% — below the non-technical rung. Rung 05’s headline 30.77% is carried by the 77% of it holding engineering diplomas.
2. A technical diploma beats a general degree, and matches a master’s
Section titled “2. A technical diploma beats a general degree, and matches a master’s”| Formal work | Entry wage | Wage at 3+ yrs | |
|---|---|---|---|
| Technical diploma | 30.77% | ₹16,000 | ₹21,500 |
| General degree | 16.20% | ₹18,000 | ₹25,000 |
| Postgraduate | 29.11% | ₹25,000 | ₹35,000 |
The general degree’s entire wage advantage over the diploma is ₹2,000 a month at entry and ₹3,500 at three years — for three or four more years of study and a 14.6 percentage point lower chance of holding a formal job at all.
The postgraduate degree pays better but employs no better: 29.11% against the diploma’s 30.77%.
How firm is that? Cluster-robust standard errors on the formal rate are ±1.21 points for the technical diploma, ±2.55 for medicine and ±0.71 for postgraduates. The diploma–postgraduate gap of 1.66 points has t = 1.18; the postgraduate–medicine gap has t = 1.25. Those three rungs are statistically indistinguishable from one another — the ordering among them is not a finding, and this analysis should not be read as saying a diploma out-employs a master’s.
What is unambiguous: engineering is far ahead of everything (t = 6.7 against medicine, t ≥ 11 against every other), and the technical diploma beats the general degree by 14.57 points at t = 11.7. That gap is the finding.
3. Wage growth is itself a privilege of education
Section titled “3. Wage growth is itself a privilege of education”Median monthly wage, entry (under 1 year in the job) to 3+ years:
All eleven rungs, in ladder order — not sorted by the growth column.
| Rung | Entry | 3+ years | Growth |
|---|---|---|---|
| 01. Below middle school | ₹12,000 | ₹12,000 | 1.00× (artefact — see below) |
| 02. Middle school | ₹12,000 | ₹14,000 | 1.17× |
| 03. Secondary (10th) | ₹13,000 | ₹15,000 | 1.15× |
| 04. Higher secondary (12th) | ₹14,500 | ₹16,500 | 1.14× |
| 05. Diploma, technical | ₹16,000 | ₹21,500 | 1.34× |
| 06. Diploma, non-technical | ₹15,000 | ₹20,000 | 1.33× |
| 07. Degree, engineering | ₹25,000 | ₹42,000 | 1.68× |
| 08. Degree, medical | ₹25,000 | ₹35,000 | 1.40× |
| 09. Degree, other technical | ₹18,000 | ₹30,000 | 1.67× |
| 10. Degree, general | ₹18,000 | ₹25,000 | 1.39× |
| 11. Postgraduate, general | ₹25,000 | ₹34,500 | 1.38× |
| 12. Postgraduate, other technical | ₹25,000 | ₹33,000 | 1.32× |
| 13. Postgraduate, engineering | ₹25,000 | ₹50,000 | 2.00× |
| 14. Postgraduate, medical | ₹30,000 | ₹50,000 | 1.67× |
At the bottom of the ladder, wage growth is close to absent — but read that from the lifecycle table below, not from this one. The tenure cells at rung 01 are not entrants versus veterans: their mean ages are 27.4, 27.1 and 29.6, and half the 37-person “entry” cell is aged 27–34. Restricted to ages 21–26 the same rung reads 1.23×, in line with middle school. The flat 1.00× is an age-composition artefact of a thin cell. The lifecycle evidence — median ₹12,200 → ₹12,000 → ₹12,000 across cells of thousands — is what actually supports the claim.
And “roughly tracks education” is the most that can be said. School rungs cluster at 1.14–1.17× and post-school rungs at 1.33–1.68×, so there is a clear break at the diploma — but inside the post-school group the ordering is not monotonic in years of study: engineering (1.68×) and other-technical (1.67×) lead, while a postgraduate degree (1.40×) sits below both and level with medicine.
This qualifies a claim in the companion graduate analysis, that the growth multiple is “broadly similar” across qualifications. It is — among graduates. Across the whole ladder it is not.
4. The gender gap closes as education rises — and medicine closes it entirely
Section titled “4. The gender gap closes as education rises — and medicine closes it entirely”Formal employment rate:
All eleven rungs, in ladder order — not sorted, and none omitted.
| Rung | Male | Female | Gap |
|---|---|---|---|
| 01. Below middle school | 3.09% | 0.71% | 4.4× |
| 02. Middle school | 5.96% | 1.17% | 5.1× |
| 03. Secondary (10th) | 10.18% | 1.77% | 5.8× |
| 04. Higher secondary (12th) | 11.84% | 2.52% | 4.7× |
| 05. Diploma, technical | 33.91% | 20.60% | 1.6× |
| 06. Diploma, non-technical | 31.44% | 13.10% | 2.4× |
| 07. Degree, engineering | 56.37% | 42.95% | 1.3× |
| 08. Degree, medical | 31.75% | 32.94% | 1.0× |
| 09. Degree, other technical | 30.06% | 20.12% | 1.5× |
| 10. Degree, general | 22.81% | 9.46% | 2.4× |
| 11. Postgraduate, general | 37.68% | 17.08% | 2.2× |
| 12. Postgraduate, other technical | 50.74% | 26.73% | 1.9× |
| 13. Postgraduate, engineering | 61.18% | 41.63% | 1.5× |
| 14. Postgraduate, medical | 64.04% | 60.55% | 1.1× |
This is a step, not a gradient. Read down the column: 4.4, 5.1, 5.8, 4.7 across the four school rungs, then it drops to 1.3–2.4 and stays there for every post-school qualification. Above that line it moves around without any further trend.
The step is solid; the peak is not. Cluster standard errors on the ratio are ±0.82, ±0.54 and ±0.31 for middle, secondary and higher secondary, so secondary’s apparent peak is t = 0.69 against middle school. Do not read the school rungs as ordered — read them as uniformly bad.
An earlier version of this table was sorted by the gap and omitted two rungs, which made the post-school scatter look like a continuing narrowing. It was not.
Engineering’s male and female medians are identical at ₹37,500 — though that exact tie is partly an artefact of a flat distribution (p45 = ₹35,000 and p55 = ₹40,000 for both sexes); the weighted means, ₹45,350 and ₹46,704, make the same point less crisply.
Medicine is the rung where the employment gap disappears — 32.94% against 31.75%. The 1.19-point female lead is not real (t = 0.24 on 485 women and 400 men); what the data supports is a tie, not a reversal. Medicine also carries the widest wage gap of any degree rung, because women in that category are nurses and men are doctors.
Two comparisons worth stating on their own:
- A woman with a technical diploma reaches 20.60% formal employment; with a postgraduate degree, 19.84%. The difference is inside sampling error, so the claim is that a master’s is no better for women than a diploma obtained six or seven years earlier — not that it is worse.
- Half the women holding a general degree — India’s most common qualification, 49 million people — are in domestic duties.
Across a working life
Section titled “Across a working life”Formal employment and mean wage at three life stages. This is a synthetic cohort, not a projection: the age-40 column describes people who are 40 today and finished their education around 2008, not what someone entering now will experience. Today’s 40-year-old graduates are a far more selected group, and the wage growth across columns mixes career progression with twenty years of inflation, which this data cannot separate.
| Rung | % formal: entry → 30 → 40 | Mean wage: entry → 30 → 40 | Wage × |
|---|---|---|---|
| Below middle school | 0.8 → 1.7 → 2.2 | ₹13,088 → ₹12,704 → ₹13,904 | 1.06× |
| Middle school | 2.7 → 4.4 → 5.4 | ₹14,120 → ₹14,516 → ₹15,571 | 1.10× |
| Secondary (10th) | 5.3 → 6.8 → 8.3 | ₹14,870 → ₹17,415 → ₹19,167 | 1.29× |
| Higher secondary (12th) | 3.5 → 10.9 → 15.6 | ₹15,648 → ₹19,581 → ₹27,138 | 1.73× |
| Diploma, technical | 18.3 → 34.0 → 48.2 | ₹16,026 → ₹24,968 → ₹36,854 | 2.30× |
| Diploma, non-technical | 15.0 → 32.5 → 34.9 | ₹15,677 → ₹23,537 → ₹37,747 | 2.41× |
| Degree, engineering | 34.7 → 63.1 → 75.6 | ₹33,771 → ₹48,719 → ₹69,834 | 2.07× |
| Degree, medical | 26.7 → 40.6 → 49.5 | ₹30,237 → ₹40,319 → ₹51,608 | 1.71× |
| Degree, other technical | 10.9 → 35.1 → 52.7 | ₹22,447 → ₹34,052 → ₹42,456 | 1.89× |
| Degree, general | 7.2 → 23.6 → 27.8 | ₹20,566 → ₹29,153 → ₹36,537 | 1.78× |
| Postgraduate | 18.4 → 32.8 → 47.2 | ₹27,238 → ₹42,344 → ₹52,440 | 1.93× |
Below middle school, twenty years of working life add 6% to the mean wage, and 2.2% ever reach a formal job. That is the floor.
The general degree plateaus after 30 — 23.6% to 27.8% in a decade, while the technical diploma runs 34.0% to 48.2%. By 40, a general-degree holder is barely more than half as likely to hold a formal job as someone with a technical diploma.
Two thin cells to respect: medicine at 40 rests on 53 people, 25 of them formally employed, and non-technical diploma at 40 on 273. Neither should be quoted as a point estimate.
Method
Section titled “Method”Full definitions are in each rung’s note; the shared rules are here.
Base. PLFS calendar_2025, visit='V1' (usual principal activity is collected only at the
first visit), ages 21–34, weighted by weight_annual. Not pooled across releases.
Rungs come from gedu_lvl, highest general education completed, split by tedu_lvl where a
technical qualification distinguishes people at the same general level.
Formal work is pas='31' (regular salaried) with ern_reg > 0 and either a written contract
(job_pas 2–4) or social security (ssec_pas not 8 or 9).
That OR leaks, and it leaks worst at the bottom. People admitted by a written contract alone
are 23.9% of rung 01’s formal count and earn a ₹10,000 median — below the ₹11,000 of those the rule
classes informal. At engineering they are 2.7% and earn ₹21,000, above the informal ₹16,000. So the
rule is doing something different at the two ends of the ladder. Requiring social security instead:
| Current rule | Social security required | |
|---|---|---|
| Below middle school | 1.66% | 1.26% |
| Degree, engineering | 52.58% | 51.20% |
| Top-to-bottom ratio | 31.7× | 40.6× |
The stricter rule widens the gradient this analysis is about, from a factor of thirty-two to a factor of forty. Every ordering in the analysis is unchanged. The looser rule is retained because it matches conventional PLFS formality measurement, and because it is the conservative choice for the claims made here — but the headline “factor of thirty” is the low end of a 32–41 range.
Wage growth is measured on tenure (dur_pas), not age, because tenure measures time in work
directly and assumes nothing about when anyone finished studying. Its code boundaries are
undocumented in our schema and were validated against people who cannot have long tenure.
The ₹6 lakh threshold used in the graduate analysis does not travel down the ladder. Below
higher secondary it is cleared by 2, 1 and 10 people. Each rung’s note reports thresholds that carry
information for it; the full grid from ₹5,000 upward is in output/ladder.csv.
Two corrections this analysis makes to the graduate analysis
Section titled “Two corrections this analysis makes to the graduate analysis”The companion work in ../plfs/entry/ is merged and has
two errors that this analysis corrects:
Its diploma buckets are not diploma holders. “Technical diploma” and “Other diploma” there are
built from gedu_lvl='12' rows carrying a diploma tedu_lvl code — graduates who additionally
hold a diploma, 4,496 people. The real diploma population is gedu_lvl='11', 6.91 million, and
was absent from it entirely. Here those 4,496 sit in the general-degree rung, where their general
education places them.
Its tenure lens had no age filter. Documented as ages 21–34, the SQL applied that bound only to the age lens, so the tenure lens ran 22 to 70. That has been fixed in place; engineering’s 3+ year median moves from ₹48,000 to ₹42,000 and its growth multiple from 1.92× to 1.68×.
And one this analysis makes to itself
Section titled “And one this analysis makes to itself”An earlier version defined “Diploma, technical” as tedu_lvl != '01', which swept in code 11,
“diploma in other subjects” — 1,890 people at 25.4% formal employment. That diluted the technical
rung from 33.4% to 29.1%. Technical now means a technical field: agriculture, engineering,
medicine, crafts.
What this does not tell you
Section titled “What this does not tell you”No causation, anywhere. People who take a technical diploma differ from those who take a general degree in ways this cannot see. Every gap here describes what two groups look like, not what the qualification did to them.
The largest rung cannot be subdivided. Arts, science and commerce are one bucket — 49 million people — because PLFS records no field of study for non-technical degrees.
Wage figures describe only those in formal work, which is 1.66% of the bottom rung and 52.58% of the engineering rung. They say what a formal job pays, not what the population earns.
Higher secondary is a waiting room. gedu_lvl records the highest qualification completed, so
undergraduates sit there until they graduate — 39% of that rung is studying at ages 21–23. Its
employment rate is a floor, and the people who leave are systematically those who would have done
best.
One year, nominal. CY2025 only, no deflation, no trend.
| File | What |
|---|---|
ASSUMPTIONS.md |
Every assumption, numbered, with what it would change if wrong |
QUERIES.md |
Every query run, including the eight that changed a conclusion or a table |
FINDINGS.md |
Every claim graded solid / directional / retracted |
rungs/ |
Fourteen self-contained notes, one per rung |
output/fresh-graduates.html |
The ladder at the fresh-graduate window, as one self-contained page |
check_notes.py |
Verifies all 2,005 published table cells against the CSVs; exits 1 on mismatch |
extract.sql |
Activity split (whole stock and fresh-graduate window) and wage distributions by rung × lens × step |
build_fresh_graduates_view.py |
Builds output/fresh-graduates.html from ladder.csv + rung_detail.csv. No query of its own |
extract_lifecycle.sql |
Formal employment and wages at entry, 30 and 40 |
extract_rung_detail.sql |
Gender, urban/rural and occupation by rung |
extract_premium.sql |
What the ≥₹6 lakh jobs are, for rungs 10 and 11 |
extract_charts.sql |
The series behind the four figures in ../EDUCATION-FINDINGS.md |
build_job_function.py |
Authors and validates the NCO group → job function map; refuses to write if any group is unmapped |
job_function_case.sql |
The map as a generated SQL CASE, embedded by extract_rung_detail.sql; build_job_function.py --check fails if the embedded copy drifts |
render_note_tables.py |
Writes the population columns and job-function tables into the rung notes from the CSVs, so none of it is hand-copied |
build_charts.py |
Draws those four figures from the extract CSVs |
output/ladder.csv |
The full threshold grid, ₹5,000 to ₹100,000 |
output/lifecycle.csv · output/rung_detail.csv · output/premium_jobs.csv · output/charts.csv |
The other four extracts |
Rebuild:
bq query --use_legacy_sql=false --format=csv --max_rows=100000 < extract.sql > output/ladder.csvbq query --use_legacy_sql=false --format=csv --max_rows=100000 < extract_lifecycle.sql > output/lifecycle.csvbq query --use_legacy_sql=false --format=csv --max_rows=100000 < extract_rung_detail.sql > output/rung_detail.csvbq query --use_legacy_sql=false --format=csv --max_rows=100000 < extract_premium.sql > output/premium_jobs.csvbq query --use_legacy_sql=false --format=csv --max_rows=100000 < extract_charts.sql > output/charts.csv
# then regenerate the map, the note tables and the figures - in this orderpython3 build_job_function.py && python3 build_job_function.py --checkpython3 render_note_tables.pypython3 build_charts.pypython3 build_fresh_graduates_view.py # the HTML view; needs ladder.csv + rung_detail.csv above
# --max_rows is NOT optional: bq defaults to 100 rows and truncates silently. It cost this# analysis the 35 smallest occupations on rung 10 once already.
# then verify every published table cell against the CSVs - exits 1 on any mismatchpython3 check_notes.pyRun check_notes.py before any commit that touches a note or an extract. Four review rounds on
this analysis found the same defect repeatedly — a number hand-copied from a CSV and left behind when
the CSV was rebuilt. It checks 2,005 published cells across all fourteen notes and fails loudly.