Back to the blog

Revising Assessment Scoring and Category Persistence

An assessment dispute exposed zeroed category breakdowns and a scoring calculation associated with compressed results. Revised scoring changed the same answer set from 140 to 108, while category persistence and forwarded-IP storage still remain unconfirmed.

Introduction

I investigated an assessment dispute and found two problems in the recorded result: the overall score was 140, but every category score was saved as zero, and the records I examined contained no earlier IP address or login history. I’ll call this anonymized example “Case A” and leave out unrelated account details. The investigation also identified compression toward a narrow score band as a problem with the previous calculation, though this one case cannot show how widespread it was.

I changed the scoring implementation, the way category scores are saved, and forwarded-IP storage. Before those changes, the stored categories offered no useful breakdown of the overall score. The revised implementation weights questions by difficulty, counts only correct answers, sends computed category scores from the calculating pages for storage, and captures the x-forwarded-for value on the user’s profile.

These are implementation changes, not confirmation that every resulting behavior works as intended. The demonstrated scoring result is specific: the same recorded answers produced 108 under the revised calculation instead of 140. Successful category persistence, IP capture under assessment traffic, and production rollout remain unconfirmed.

The Rule That Shipped

In lib/onboarding/scoring.ts, each question’s contribution now depends on its difficulty, and only correct answers contribute to the score. This replaces the calculation associated with the reported compression toward a narrow range. The changes were deployed to development; “shipped” here does not mean production availability has been established.

The evidence does not specify the exact difficulty-weight multipliers or the guessing-correction formula referenced during development. Without those details, I cannot give a complete numerical specification. Counting only correct answers does not exclude answers that were guessed correctly. Difficulty weighting, by itself, does not demonstrate assessment validity either. Neither property establishes that the revised score measures ability more accurately.

Two related changes address what gets stored with the result. The calculating pages now send their computed category breakdown for persistence instead of leaving categories as zeros. Assessment sessions also capture the x-forwarded-for value for storage on the user’s profile. Both changes add ways to save useful context, but confirming that the writes succeed and that the values can be read back requires separate checks.

Worked Example

Case A gives a bounded before-and-after comparison. The input was the existing recorded assessment answer set. Under the previous calculation, the stored overall score was 140 and every stored category score was zero. Recalculating those same answers with the revised difficulty-weighted, correct-answers-only algorithm produced 108, a decrease of 32 points.

Because the answer set stayed the same, this compares two calculations rather than two assessment attempts. It shows that the revised algorithm changed this result. It does not show which individual answers or difficulty tiers account for the difference; no question-by-question attribution is available. It also does not establish that 108 is independently calibrated against an external measure.

I can point to a concrete change in output without treating it as proof of improved accuracy or a correction across the assessment population. What this case establishes is a recalculated score of 108. It does not establish that the historical record was overwritten, that its category breakdown was repaired, or that other historical assessments were recalculated. Those claims would need separate evidence about persistence and migration.

Challenges and Tradeoffs

Changing the calculation and fixing persistence solve different problems. A category-only change could make breakdowns available while leaving the overall calculation untouched. A scoring-only change could alter the final number but still leave it unexplained if the categories failed to save. These are retrospective design alternatives, not options I can claim to have evaluated during implementation. The implemented work addresses both, but each still needs its own verification.

The formula change also limits comparisons between old and new results. Case A shows that identical answers can produce different scores under the two calculations. Historical and revised scores therefore should not be treated as equivalent without identifying which calculation produced them. The evidence does not establish a historical backfill or a policy for presenting those differences.

Forwarded-IP storage has a different limitation. A header value saved on a mutable profile is metadata, not necessarily a retained session history or proof of identity. The evidence does not establish trusted-proxy handling, interpretation of multiple forwarded values, or retention of earlier values. Behavior when the header is missing is also unverified. Even successful storage would leave those questions open, so this change should not be described as resolving auditability.

Verification Process

I have evidence for two completed checks: the same recorded answer set produced 108 under the revised calculation instead of 140, and the scoring, category-persistence, and IP-storage changes were deployed to development. That establishes a changed scoring output and a deployment destination. It does not establish successful production operation or end-to-end correctness of the new storage paths.

The next persistence check would follow a completed assessment from calculation through storage and read-back. It should compare the computed category values with the saved values, rather than accepting a nonzero display as proof. A legitimate zero must remain distinguishable from a missing or failed write. Failure handling also needs checking so that an unsuccessful save does not silently present a breakdown as persisted.

IP verification would require checking which value is received, how it is interpreted, and what remains on the profile after later sessions. None of those checks is established as complete here. No earlier IP address or login history was found for Case A in the examined records, so those records cannot retrospectively verify the earlier sessions through IP data. That does not establish that no other evidence could exist.

Calibration and broader score-distribution checks also remain outside the demonstrated result. One recalculation cannot establish whether compression has been corrected across assessments.

Conclusion

I changed three implementation paths: difficulty-weighted, correct-answers-only scoring; persistence of computed category breakdowns from the calculating pages; and storage of forwarded-IP metadata on the profile. For the same recorded answers, the worked result changed from 140 to 108. Deployment to development is established; production rollout is not.

The remaining limits matter. The evidence does not provide the exact difficulty multipliers or the guessing-correction formula. Category persistence and IP capture still need end-to-end confirmation, and profile metadata does not establish a session audit trail. Earlier IP and login history were absent from the records examined. This work provides a changed calculation and supporting storage paths, not yet proof of calibration, complete historical repair, or resolved auditability.