# ADR-151 Retire `jee_diag.py` — Elo Adaptive Practice Is the Single Scoring System

## Status

Accepted, 2026-09-11.

## Status History

```yaml
status_history:
  - date: 2026-09-11
    status: Accepted
    changed_by: claude (DL session, advisor-endorsed, hkl-confirmed)
    reason: >
      Two independently-built systems on two machines were found to cover the same
      ground for the same student. Recorded as an ADR rather than only a memory note
      because the decision needs to be readable from EITHER machine's session — DL2's
      own memory still named the retired tool as its highest-value unbuilt piece at
      the moment this was written, and a future DL2 session reading only its own
      history would not otherwise know this was resolved.
    changed_via: /adr skill inside a Claude Code session on DL, via ssh
```

## Context

DL deployed **Elo adaptive practice** live 2026-09-08 inside the yesha-jee suite
(`https://yesha-jee.srv1111289.hstgr.cloud/`) — one-sided Elo rating over the full
14,973-question JEE Main PYQ pool, integrated with test-mode and `progress.html`, hkl's
§6 framing decisions already answered and matching the shipped defaults.

Independently, on 2026-08-30, DL2 (`DESKTOP-F0DH68L`, Yesha's/hkl's second laptop) built
`Documents\jee-datasets\jee_diag.py`: a terminal-CLI diagnostic engine — Elo rating,
confidence gate, item selection, attempt log — over its own separately-sourced
2,822-question `jee.db` (eQOURSE + Abhay557 + a jeebench-derived slice). Neither session
was aware of the other's build until a 2026-09-10/11 DL↔DL2 relay session (see
`session_2026_09_10_dl2_relay_jee_diag_and_aiats_vps.md`, DL memory) surfaced both at once.
DL2's own handoff document still named a "/jee-diagnose skill" as its highest-value
unbuilt piece at the moment this was found — the two systems were on a collision course
toward disagreeing about the same student's ability estimate.

Both sessions independently stopped rather than decide unilaterally which system should
win, and flagged it to hkl. hkl asked for `advisor()`'s read ("take advice from advisor
keeping the target in mind" — the second use of this exact delegation phrasing, which
promoted it to a standing pattern, see `feedback_advisor_keeping_target_in_mind_delegation.md`
in DL memory), then confirmed the recommendation via `AskUserQuestion`.

## Decision

Retire `jee_diag.py` as a scoring/diagnostic engine. The live Elo adaptive-practice system
on `yesha-jee` is the single system that scores Yesha's ability going forward. `jee_diag.py`
and its dependency `jee.db` are **archived, not deleted** — copied to `/opt/jee-diag/` on
this VPS at hkl's own explicit request (a separate instruction, given before this ADR was
written), outside every docroot, no web route referencing the path.

**Decision Maker:** hkl, confirmed via `AskUserQuestion` ("Retire jee_diag.py (recommended)"),
after advisor's recommendation was put to him directly.

## Why (the discriminating facts, from advisor's review)

- **Zero attempts ever recorded against `jee_diag.py`.** DL2 confirmed `progress.json`
  (its own attempt-log file) does not exist on that machine — the engine has never been run
  against Yesha. Retiring it costs no accumulated history, because there is none.
- **Elo is already the system in use**, not a competing proposal: deployed, hkl-signed-off
  on its §6 display/framing questions, integrated with test-mode and `progress.html`, over
  6x the question pool (14,973 vs 2,822).
- **`jee_diag.py` is a terminal CLI** — meaningfully higher friction than a web page Yesha
  already has bookmarked, which cuts directly against project_student_jee's own §7 rule
  ("under 5 min/day of friction or it dies in three weeks").
- **Merge was considered and rejected**: `jee.db`'s eQOURSE/Abhay557 provenance is
  unverified (no license file, no source manifest — the same gap already flagged for the
  main PYQ dataset), and its jeebench-derived slice is already present in
  `jee_advanced_explorer.html`. There is nothing in `jee.db` that isn't either
  unverified-provenance content or already-folded-in content.

## Implementation Notes

- Archive location: `/opt/jee-diag/` on this VPS — `jee.db` (4,657,152 bytes, sha256
  `c32d66145d7650f8f7c54d89818883665363b4a9849a0d23bb68a6947c43af40`), `jee_diag.py`
  (14,273 bytes), `jee_query.py` (7,842 bytes, optional read-only search CLI). Verified
  server-side: DB opens on this VPS's own python3, reports 2822 questions — not a
  truncated/corrupted transfer.
- Superseded-notice README written: `/opt/jee-diag/README-SUPERSEDED.txt`. DL2's own
  retirement confirmation is separate and still outstanding — DL2 was offline when the
  retirement was confirmed; hkl was handed a paste-ready line to deliver the confirmation
  directly, which includes asking DL2 to check whether
  anything else on that machine — study-notes PDFs, a weekly goal-setter — still reads
  `jee.db`/`jee_query.py` before marking the retirement complete).
- No code changes to the live `yesha-jee` deployment — this ADR retires a separate,
  never-deployed tool; nothing production-facing changes.

## Alternatives Considered

- **Merge the two question pools/engines** — rejected: `jee.db`'s non-jeebench provenance
  is unverified, and its verified (jeebench) content is already in the JEE Advanced
  explorer. There was no unique content to merge in.
- **Run both, let hkl or Yesha choose per-session** — rejected: two systems silently
  producing different ability estimates for the same student is worse than either alone,
  and `jee_diag.py`'s CLI-only interface is higher-friction than the web tool she already
  uses.
- **Keep `jee_diag.py` dormant on DL2, decide later** — rejected as a false economy: the
  duplication was already actively confusing both sessions' own handoff documents (DL2's
  named it as a priority build); leaving it undecided would have let a second implementation
  of adaptive scoring keep drifting from the live one.

## Consequences

**Positive:**
- One scoring system, one source of truth for Yesha's ability estimate — no risk of two
  tools disagreeing about the same student.
- Zero cost to retiring — no attempt history existed to lose or reconcile.
- `jee.db`'s content is not lost — archived and checksummed, retrievable if a future
  session finds a genuine use for its non-overlapping content (none identified as of this
  ADR).

**Negative / risks:**
- DL2's own confirmation that the retirement instruction was received and acted on had not
  been observed as of this ADR (DL2 was offline). A future session should verify this
  landed, and that the "anything else still reads jee.db" dependency check was actually
  run, before treating this ADR's implementation as fully complete on DL2's side.
- ~~The archived `/opt/jee-diag/` copy currently has no superseded-notice README~~ FIXED same session: `README-SUPERSEDED.txt` written. Would have been a risk if a future
  VPS session could mistake it for a live, deployable tool if it finds the directory without
  reading this ADR first.

## Related Decisions

- ADR-149 (`procedure`-kind pool, not filter) — same project, same precedent for JEE-support
  decisions living in this ADR series rather than only in DL-side memory.

## References

- Session: `session_2026_09_10_dl2_relay_jee_diag_and_aiats_vps.md` (DL memory)
- Project narrative: `project_student_jee.md` (DL memory) — 2026-09-11 entry
- Standing pattern: `feedback_advisor_keeping_target_in_mind_delegation.md` (DL memory)
- Coordination rule this session also produced: `feedback_multi_session_coordination.md`
  §6 (DL memory) — on why the retirement instruction was handed to hkl as a paste-line for
  DL2's own channel rather than relayed
- Archive: `/opt/jee-diag/` on this VPS
