Read the ga flag in the ranking, and label the rooms a department locks - #96
Merged
Conversation
…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
…mdb2-89 # Conflicts: # sw.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
gais now a term intierOf(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 (rowFromemits 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:
gais 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
gaat 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.jsonwith node before relying on them. The issue's cross-tabulation still holds exactly, cell for cell:382 rooms are in
PREFERRED_TYPESand 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()plusshape()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. Thegatier alone: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 touchTYPE_ORDERor the capacity term. Onmain,TYPE_ORDERwas still{'1B':0, LCTR:1, '1C':1, SMNR:2, '1A':2}andcompareRowsstill sorted seats descending, largest first. So option 3 was implemented here:1C/LCTRdropped below1A/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.?? 0also 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.shape()'snearestkeeps 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 injs/engine.jsandjs/app.js.spikes/engine.vendor.jsre-copied, and the shell re-stamped.What I did NOT satisfy
gatier 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 recordinggaper room walked is still unbuilt, so the next tuning pass still has no evidence.scoreOfpriced 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.gaas 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.mdstill quotes the old five-tiertierOfand says "seats are not in the sort at all". It was already stale on the seats claim before this PR —typeRankand seats have been incompareRowsfor 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.🤖 Generated with Claude Code
https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM
Generated by Claude Code