Skip to content

Read the ga flag in the ranking, and label the rooms a department locks - #96

Merged
EnesYilmazcode merged 4 commits into
mainfrom
claude/open-issues-eymdb2-89
Sep 2, 2026
Merged

Read the ga flag in the ranking, and label the rooms a department locks#96
EnesYilmazcode merged 4 commits into
mainfrom
claude/open-issues-eymdb2-89

Conversation

@EnesYilmazcode

Copy link
Copy Markdown
Owner

What changed

ga is now a term in tierOf (js/engine.js), so a general-assignment room outranks a departmental one before walk time is consulted, the same way published hours already outrank unknown hours. The flag reaches the row (rowFrom emits it), and a departmental room carries one word, departmental, on the list row and on the room screen.

The tier space doubled from 5 to 10: ga is the innermost of the three terms, inside the wait and the window. A departmental room that is free when you arrive still beats a general-assignment one you would wait an hour for — who holds the key is a smaller fact than whether the door is open at all.

A row with no ga at all is treated as general assignment, not departmental. An index built before the 2026-08-27 pull carries the field on nothing, and demoting all 425 rooms would be worse than the behaviour this replaces.

Closes #89

The numbers, re-derived

Re-derived from data/rooms-1268.json with node before relying on them. The issue's cross-tabulation still holds exactly, cell for cell:

1B  classroom      GA 268   not GA  41
1C  lecture hall   GA  55   not GA   0
1A  seminar room   GA   3   not GA  15
2P  computer lab   GA   1   not GA  19
2Q  computer lab   GA   0   not GA   7
5K  conference     GA   0   not GA  12
others             GA   0   not GA   4
                   ------          ----
                      327            98      of 425 rooms

382 rooms are in PREFERRED_TYPES and 56 of them are not general assignment (41 classrooms + 15 seminar rooms), so the first rung was offering them indistinguishably. Every room in the index carries the field; none are missing it. These counts are now asserted in a test, so a term that ships without the flag fails rather than silently losing the signal.

What it does to the answer

Replaying rank() plus shape() over the committed index from the Oval, every half hour 08:00 to 20:00 on the 2026-09-14 to 18 weekdays at asks of 30 and 60 — 250 lists, 9,102 shown rows. The ga tier alone:

  row one is a departmental room     77 lists 30.8%  ->  0 lists 0.0%
  departmental rows in the top ten            31.7%  ->  0.3%
  departmental rows anywhere shown            30.4%  ->  15.5%
  row one changed                                        77 of 250 lists

Nothing is hidden. The rows are still there, further down, carrying the label.

Option 3: needed, not already landed

I checked. PR #80 merged and closed #62, but it landed shape() — the walk bound and the per-building fold — and did not touch TYPE_ORDER or the capacity term. On main, TYPE_ORDER was still {'1B':0, LCTR:1, '1C':1, SMNR:2, '1A':2} and compareRows still sorted seats descending, largest first. So option 3 was implemented here:

  • 1C/LCTR dropped below 1A/SMNR. All 55 lecture halls are general assignment so the rows were never lies, but they run 48 to 727 seats, median 100, against a median of 34 for the 309 classrooms.
  • Seats now tiebreak toward the room one person asked for. Unknown capacity still sorts last, where ?? 0 also put it.

With those two changes and nothing else, over the same 250 lists: the mean capacity of a shown row falls 60.3 → 47.9 seats, rows of 100 seats or more 8.3% → 4.6%, and row one 36.4 → 22.3 seats.

Option 4 (filtering non-GA rooms out of the first rung) is not implemented, per the issue.

Tests

npm test: 670 tests, 666 pass, 0 fail, 4 skipped (main is 666/662/0/4). Four new tests, including the one the issue asks for by name: two rooms, same building, same window, same type, same seats, one GA and one not — GA ranks first, and the assertion checks it is the tier that did it, not the id tiebreak.

Two existing tests changed rather than broke, both recorded in the diff with why:

  • tierOf's numbers now run 0 to 9.
  • The downtown empty screen names Jennings Hall instead of Pomerene Hall. 8 rooms tie at exactly 71 minutes across those two buildings and shape()'s nearest keeps the first the ranking hands it, so the seat tiebreak picks between Jennings 50 (35 seats) and Pomerene 150 (62). The walk, which is the number that sentence is about, is unchanged.

sw.js's gzip figure was re-measured rather than left stale: the shell went 84,201 → 86,219 bytes, 1,862 of it comments in js/engine.js and js/app.js. spikes/engine.vendor.js re-copied, and the shell re-stamped.

What I did NOT satisfy

  • Walk to twenty rooms the app calls free and record what was actually true #26, the physical ground-truth walk of twenty rooms, remains open and cannot be done from here. I did not fake it. Every tuning decision in this PR is therefore still an estimate: the ga tier is a hard reorder chosen because the backlog already decided it, not because anyone has counted how often a departmental door is actually locked. Walk to twenty rooms the app calls free and record what was actually true #26's checklist recording ga per room walked is still unbuilt, so the next tuning pass still has no evidence.
  • The 700-seat lecture hall done-when is only half met. The capacity term is a tiebreak, so it fires at equal walk and window, which is what the issue asked for in option 3 ("does not tie a 26-seat classroom at equal walk"). It does not move issue The ranked list is a building dump: 40 rows, 11 buildings, and PAES takes 12 of the slots #62's screenshot: on Saturday 2026-09-19 from the Oval, Independence Hall 100 is a 2 minute walk and the next free room is 6, and Independence Hall contributes exactly one room to the index, so nothing at a comparable walk exists to outrank it. Moving that row would need a capacity penalty in scoreOf priced in minutes, which is a guess Walk to twenty rooms the app calls free and record what was actually true #26 has not supplied yet. Deliberately not invented.
  • Option 2 (ga as a score penalty) was not built, per scope. Option 1 is the harder of the two and is what the backlog asked for; if the walk comes back saying departmental rooms are usually fine, option 2 is the softening.
  • docs/README-CORRECTIONS.md still quotes the old five-tier tierOf and says "seats are not in the sort at all". It was already stale on the seats claim before this PR — typeRank and seats have been in compareRows for a while — and it reads as a record of a past README review, so I left it rather than rewriting someone else's document. Worth a follow-up.
  • No screenshots were re-shot and the change was not driven in a real browser; the evidence here is the replayed engine over the committed index plus the test suite.

🤖 Generated with Claude Code

https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM


Generated by Claude Code

…artment locks

The index has carried `ga` on every room since the 2026-08-27 general-assignment
pull and the client never read it. `grep -rn "\.ga\b" js/` returned nothing.

Re-derived on the committed index, data/rooms-1268.json, 425 rooms: 327 are on
the Registrar's general-assignment list and 98 are not, and 56 of those 98 are
types the first rung offers by default, 41 type-1B classrooms and 15 type-1A
seminar rooms. They were ranking indistinguishably from a room anybody can walk
into. This is the decision docs/BACKLOG.md parked, which asked for them "ranked
below general-assignment rooms, with a one-word label on the row".

`ga` is now a term in tierOf, so it is settled before walk time, the same way
published hours already beat unknown hours. It is the innermost of the three
terms: a departmental room that is free when you arrive still beats a
general-assignment one you would wait an hour for. Replaying rank() plus shape()
from the Oval, every half hour 08:00 to 20:00 on the 2026-09-14 to 18 weekdays
at asks of 30 and 60, 250 lists and 9,102 shown rows, this term alone:

  row one is a departmental room     77 lists 30.8%  ->  0 lists 0.0%
  departmental rows in the top ten            31.7%  ->  0.3%
  departmental rows anywhere in the list      30.4%  ->  15.5%

Nothing is hidden. The rows are still there, further down, and they now carry
the word "departmental" on the list row and on the room screen.

Issue #62's other half, which PR #80 left alone: 1C, the lecture hall, dropped
below the seminar room in TYPE_ORDER, and the seat tiebreak now runs toward the
room one person asked for instead of the largest one on offer. All 55 lecture
halls are general assignment so the rows were never lies, but they run 48 to 727
seats, median 100, against a median of 34 for a classroom. With those two
changes and nothing else, over the same 250 lists the mean capacity of a shown
row falls from 60.3 seats to 47.9, rows of 100 seats or more from 8.3% to 4.6%,
and row one from 36.4 seats to 22.3.

It does not settle #62's screenshot. Independence Hall 100 is a 2 minute walk
from the Oval and the next free room on that Saturday is 6, so a tiebreak that
only fires at an equal walk cannot reach it. Moving it would take a capacity
term in scoreOf, priced in minutes, and #26's ground-truth walk has not happened
yet, so there is nothing to price it against.

Two tests changed rather than broke: tierOf's numbers now run 0 to 9 because the
tier space doubled, and the downtown empty screen names Jennings Hall instead of
Pomerene Hall, which is the seat tiebreak choosing between 8 rooms that tie at
exactly 71 minutes.

670 tests, 666 pass, 0 fail, 4 skipped, up from 666/662 on main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM
…nswered it

The parked decision asked for departmental rooms to be ranked below
general-assignment ones with a one-word label, and 882471a builds exactly that.
The banner also corrects the two figures in the question itself: the index it
was written against held 871 rooms and 77 non-GA type-1B rooms, and the shipped
index holds 425 and 41.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM
Review of this branch could not reproduce four numbers written into
permanent comments. The ranking itself held up -- the comparator was
brute-forced over 4,396 real rows and 9.66M pairs with no antisymmetry or
transitivity violations -- so what shipped wrong was the evidence, in a file
whose comments are only worth reading because their numbers are real.

Re-replayed rank() plus shape() from the Oval, half-hourly 08:00 to 20:00
across 2026-09-14 to 18 at asks of 30 and 60, against this file as it stood
on main:

  row one departmental   said 77 lists (30.8%)   is 32 lists (12.8%)
  top ten departmental   said 31.7%              is 30.8%
  all shown rows         said 15.5%              is 15.4%
  row one mean capacity  said 36.4 -> 22.3       is 45.6 -> 25.3
  mean shown capacity    said 60.3 -> 47.9       is 60.7 -> 52.7

The 30.8% was the top-ten figure standing in the row-one slot, which is how
a real measurement became a wrong one. Both blocks now quote a single run
against a single baseline -- this whole commit, not one term in isolation --
and say so, because the earlier text left no way to tell which run each
number came from.

Independence Hall 100 is a 5 minute walk from the Oval with the next free
room at 7, measured at four times on 2026-09-19; the comment said 2 and 6.
The conclusion was right and both figures were not.

sw.js quoted `gzip -9 -c <file>`, which stores each basename in the FNAME
header and reads 142 bytes high across these twelve files, then explained
the gap as two gzip versions disagreeing. There was no disagreement:
through the documented pipe, GNU gzip 1.12 and node's zlib agree to 0.009%.
Shell is 86,783 bytes, exact. SHELL_CACHE is back to 74f888c -- a stamp is
the committing job's, and this one already named main's tip rather than its
own head.

The row label was a <b>, so it took `.r-win b` at --fg weight 650 and became
the only emphasised token on a line that is otherwise --dim: the reason a
room ranks low, shouting over the reason it is on screen. It is plain text
now, after the middot the seat count already uses. Its class was styled
nowhere. The room screen printed the bare word while the row it came from
spoke a full sentence, so it carries the sentence too.

engine.test.mjs asserted unknown-hours rows have `tier >= 3`. Tiers
renumbered to 0,2,4,6,8 when ga became the innermost term, so that bound
still passes and now also admits tiers 3, 4 and 5 -- every one a room whose
hours are known. It is >= 6.

672 tests, 668 pass, 0 fail. The two new label tests fail against this
branch's previous app.js.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM
@EnesYilmazcode
EnesYilmazcode merged commit 60dea3d into main Sep 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants