What were we
measuring?
Across one term, 1,070 enrolled students left 57,033 saved attempts and 777,874 per-question scores in the exam portal. Every keystroke that mattered was timestamped. That record answers a question the marks themselves cannot: did the graded assignments measure capability, or something else?
They measured something else. Students who routed one shared URL scored 91.3% on graded assignments and 50.5% on the timed exam. Students who never touched it scored 64.2% and 59.1%. The assignments did not merely fail to detect the shortcut — they inverted, ranking the students who learned least at the top.
This is not a story about cheating. Under the course's stated policy — "Anything is allowed. Help from the Internet, ChatGPT, friends, pets, hacking, … anything" — not one student in this review broke a rule. The policy was not the failure. The failure was that the assessment offered no question a single shared service could not answer.
"Anything is allowed. Help from the Internet, ChatGPT, friends, pets, hacking, … anything. Just get the job done!"
— Instructions shown at the top of every graded assignment, 26T2
The term in numbers.
Before anything can be fixed, the shape of the term has to be visible. Nine graded assignments, two projects, one timed exam, and 5,305 refused saves. Participation held up better than the room suggested — 632 students still submitted GA8, 59% of those enrolled — while live-session attendance fell from roughly 150 to zero.
Those two facts belong together. Hundreds of students kept submitting assignments while nobody attended the teaching, which is the first clue about what the assignments were actually asking for. The second clue is in the clock: the median student's work on an assignment fell from 22 hours on GA0 to 20 minutes on GA8.
effort · median first-to-last save span, accepted attempts onlyparticipation · /stats access log joined to submissionsFive cohorts.
One broken ruler.
Every student who sat the Remote Online Exam can be placed on a single axis: how many graded questions they answered by submitting a URL that other students also submitted. That is an observable fact in the answer text, not an inference about intent.
The Remote Online Exam is the control. It ran in a fixed 45-minute window on questions nobody had seen, so a shared service cannot sit it for you. Comparing each cohort's assignment average against its exam average is therefore a direct test of whether those assignment marks meant anything — and the five cohorts answer it in five different ways.
Read the cards below as operational descriptions, not character judgments. Nobody in any of these bands broke a rule. The differences between them are differences in what the questions allowed, and each band needs a different fix.
inversion · 771 students with both an assignment average and an ROE scoreinversion_scatter · one point per studentTwenty-two hours became twenty minutes.
GA0 is what this course looks like when nobody has the answers yet: 22 hours of work, 7% on the first attempt, 63% by the end. Students iterating, failing, improving. That is a functioning assignment, and it existed in week one — the course was capable of producing one.
By GA8 the median student finished in twenty minutes, scored 74.6% on their very first save, and a quarter of the cohort cleared 95% before iterating once. There was nothing left to iterate on. They arrived with the answers.
This did not start in May. January 2026 decayed too — but May decayed from a lower start and faster, hitting a fifteen-minute median by GA4, a level the previous term did not reach until GA5. Whatever was spreading, it spread faster the second time, because it did not have to be built again.
Set against the finalised marks, one component stands apart. The assignments settle between 66% and 92%, both projects land in the sixties and eighties — and the ROE alone sits at 50.3%. It is the only component where a shared endpoint could not answer for anyone.
efforteffort_two_terms · comparable GAs onlycomponent_scores + calendar · finalised marks from the marks record, portal scores from the submission logOne address,
five hundred students.
Many assignment questions asked students to deploy a working service and submit its URL. The grader would call the URL, check the response, and award marks. The answer to the question was, literally, an address.
The most-submitted address of the term was tds-roe-solver-api-t12026.onrender.com. The t12026 is not decoration — that service was built for the January 2026 Remote Online Exam. It was still running in May. It was still running in August. Over the term, 514 distinct students submitted it as their own deployed service, across 46 questions in 7 of the 9 graded assignments.
It was never the only one. And for GA8, somebody deployed one called tds-ga8-shared-…. Nobody was hiding this.
127.0.0.1:8000, and roughly 240 more submitted other localhost ports.endpoints · threshold 20+ distinct studentsendpoint_adoption · week beginning, ISTendpoint_diffusion · click any column heading to sortidentical_answers · answers of 20+ characters shared by 25+ distinct studentsServer-side questions made it worse.
The design intuition was reasonable: a question whose answer is a live service the grader calls should be harder to fake than a static answer. You have to actually build something. The data says the opposite, and it says it clearly.
The reason is structural. When the answer is a URL, one working service satisfies every student who holds the link. Server-side questions concentrate the entire cohort's work into a single artifact that costs nothing to copy. They are the most farmable question type in the set, not the least.
question_resistanceThe score students saw
was not the score they got.
Project 1 awarded portal marks for an answer being present. The analytical judgment came later, offline. Which means that at the moment a student clicked save, the portal told them something that was not true.
Ninety-nine students in a hundred closed the Project 1 tab having been told they scored 12.5 out of 12.5 on Question 1. Then the offline evaluation ran, weeks later, and took much of it back. What followed was the largest single category of forum traffic in the term.
Be precise about what those students were arguing. They were not disputing a hard mark. They were disputing a mark the system had already promised them. That argument was unwinnable, and it did lasting damage: it taught the whole cohort that offline evaluation was arbitrary, which then poisoned the reception of Project 2's grader — which did not deserve it.
p1_portal_vs_realcomponent_scoresThe judge is better
than its reputation.
The loudest grievance of the term was that offline LLM evaluation is a black box. That is two different complaints, and they deserve different answers.
For Project 1 and ROE the complaint is valid. No rubrics, judge prompts or per-question offline scores survive. A student who believes they were misgraded has nothing to appeal against — and the course team has nothing to defend with. That is not a grading disagreement; it is an absence of record.
For Project 2 it is not valid, and Project 2's grader is the template worth building on. It published the rubric, scored every submission across 126 named dimensions, quoted the student's own text as justification for each score, and gave each student a code to look up their breakdown. It also discriminates — but its two real faults are compression and length-bias, not opacity.
p2_effort_vs_gradep2_verdictsp2_scatter · 710 studentsp2_dimensions · dimensions graded 400+ timesThree hundred and forty-eight
spellings of one instruction.
Project 1 Question 2 required a Google Drive folder, shared with the graders, under a stated name. Both halves of that requirement failed at scale, and the failure was only discovered weeks later when a human went looking.
It is tempting to read that as carelessness, and the course team did — these were called silly mistakes, and students were told they should have read the instructions. Both sides were right, which is why the argument never resolved: the instruction was clear, and the students genuinely had no way to know they had failed it.
Every one of these failures was machine-checkable at submission time. The portal could have called the Drive API, confirmed access, checked the name, and refused the save with a reason. A rule that 600 people implement 348 different ways is not a discipline problem. It is a missing validator.
dumps/q-interview-requirements-audio-pending-access.csv, query drive_accessfolder_names, folder_name_countThe course kept
colliding with itself.
Every exam config carries an open date. The portal records the first save that actually succeeded. The gap between the two is how late the assignment really shipped — and GA1 shipped 28 days late.
The churn did not stop at release: the GA3 and GA5 question sets took ten commits each after their nominal open date, while students were working on them. The content repo tells the same story — 44 commits during the term, many of them pure date corrections, and Week 8 teaching content landed on 26 August, eight days after GA8 was released. The assessment shipped before the material it assessed.
Slippage has to be absorbed somewhere, and here it was absorbed by compressing the end of the term: GA6 open to 9 August, GA5 extended to 10 August, ROE sitting on 2 August. Three assessments and an exam inside a fortnight.
calendarrejectionsga5_dailycalendar · commit counts from the exam repo's git historyWhen students work.
When students ask.
The timing data turns the review into an operations question. Roughly a third of every component's saves land between 22:00 and 06:00 IST, and close to half of Project 1's landed in the final twenty-four hours. These are working students fitting a degree around a job.
Any support model built around daytime availability is serving a different course than the one being taken. The forum follows the same rhythm, which means pinned answers, validator reliability and TA coverage matter most at predictable moments — and those moments are nights and weekends.
deadline_impactdeadline_impact, timing_deadlinesubmission_rhythm · times ISTforum_rhythm · times ISTsubmission_heatmapforum_heatmapA grievance desk wearing
a classroom's clothes.
281 threads were created in the course category during the term, carrying 1,816 posts. Labelled by what each was actually for, from its own text: 88.3% administrative friction — marks, bugs, deadlines, schedules, rules. 6.0% about learning the material.
One hundred and twenty-seven marks disputes. Forty-eight portal bugs. And four threads in the entire term asking for help with the actual task. It got worse as the term went on, from 55% marks-and-bugs threads in May to 72% in August.
Here is the counter-intuitive part. The obvious diagnosis is that support was slow, so students got angry. That is not what happened. Median time to a first reply was two to three hours, every single month, and only 17 of 281 threads went unanswered. By any normal measure this forum was well served. It was simply serving the wrong function — students were not asking how to do the work, they were contesting the score.
forum_family · method in classify_forum.pyforum_intentforum_friction_trendforum_monthlyforum_top_topicsStudents talked.
The team resolved.
The May 2026 course team was seven people — the professor, two instructors and four teaching assistants — plus five Learning Assistants working against a separate exam-dev deployment. Two ex-TAs from the January 2026 term also kept answering. This chapter takes that roster and asks the forum what each of them did with it.
The headline is a genuine split. The team wrote only 26.4% of the term's posts, so on volume the forum is a peer network. But they wrote 158 of its 184 accepted answers — 86%. Students do the talking; the team does the resolving. Both of those are worth knowing, and the second one is usually missed.
The load inside the team is very unevenly spread: two teaching assistants account for 297 of the 479 team posts, and one of them holds 93 of the 158 accepted answers. The two roster accounts that never posted at all are both Learning Assistants, covered separately below.
coveragerespondersexam-dev deployment rather than production, so their bug-finding leaves no trace in this dataset. On the forum, one of them posted twice and the other four never posted. Whatever the programme achieved, it achieved it invisibly — which is itself the problem: there is no record to review, credit or improve.Five causes.
One test.
Ordered by how much of the damage each accounts for, and paired with the change the data supports. Every one is actionable with infrastructure that already exists.
Underneath all five is a single design target, and it is falsifiable: every graded component should rank students in roughly the same order as a timed, unseen-question exam does. Where it doesn't, the component is measuring access, not capability. That can be checked in week one rather than in September.
How to read this data.
Everything here is descriptive. Where a relationship is causal the text says so and gives the mechanism; where it is only an association, it is labelled as one. Nothing in this review identifies a student as having broken a rule, because under the term's stated policy none of them did.
The whole document is reproducible. Raw data is pulled by collect.py, normalised by build.py into a DuckDB database, and queried by export_story.py — one named query per figure. This page computes no statistics of its own; every panel names the query behind it. A full rebuild from raw takes under a minute.