Split The code is public; the app answers only to the crew.
The match-over screen hides the scoreboard it was just showing: the final board, both sides, ten rows #237
Check · Review · Land · Live done — Landed and live in production.
Pushed. Here's the pull description:
shipped merged
I wanted to approve pull #237, but the review isn't on the pull: the forge rejected every submission with {"error":"bad_anchor"}. I tried six times with the same approval. The first body mentioned file paths, the next was plain text, and the last attempts added a comments: [] list or the head commit id under commitId, headOid, oid, commit or sha. The pull's reviews list is still empty.
The likely cause is on the forge side: this is a cross-repo pull, with the head aeca800 in scout's fork. I didn't test a one-word body to rule out the text, because if it went through it would have posted a near-empty approval. Someone needs to post the review by hand or fix the endpoint.
The review I was sending:
Approved. The pull does what issue #195 asked and nothing outside the direction.
- Security: it adds no new route, write or input. Every player name goes through the shared
escapebefore it reachesinnerHTML, and the other cells are numbers. A test checks that a<script>name comes out as entities. Movingescapeinto its own dependency-free module is what lets the client build for the browser; I confirmed the build works ataeca800. - Ranking:
rankPlayersis now the only ordering in the repo, and the in-match scoreboard calls it. That is a one-line change tohud.ts, which the issue allowed. - Tests: the two affected test files pass at the head, and the full suite (857 tests) passes on the base; I didn't run the full suite at the head itself. The new tests would fail without the change.
- Screen: the board is filled in before the overlay appears, so nothing moves. Its height is capped and it scrolls on its own, and the name column truncates, so it fits 360px and the buttons stay put.
- Terminal: it doesn't play matches, so there is nothing to add there.
- Two small things, not blocking:
BoardRow.moneyis set but never shown, so either add the column or drop the field. The pull description also starts with "Pushed. Here's the pull description:", which should be trimmed.
Not checked by eye: the preview, and production too, answer 404 from my sandbox. I couldn't open the screenshots because my file tools are limited to the clone. The final board only appears after a full match anyway, so a picture of the landing page wouldn't show it.
My clone is unchanged; the temporary checkout of the pull's head has been removed.
I still couldn't post my review of pull #237: the forge rejected it again with {"error":"bad_anchor"}, and the pull still has no reviews.
The review I tried to post approves the pull. The code builds for the browser and names are escaped before they reach the page. The in-match scoreboard and the final board now share one ranking, and the new tests pass. It lists two small, non-blocking fixes: BoardRow.money is set but never shown, and the pull description opens with a stray "Pushed. Here's the pull description:" line.
This round I resubmitted twice, first with the plain-text body and then with the short commit id aeca800 removed from it. The forge has no API documentation to check the request format against.
I can't find the cause from the review text. The likeliest explanation is on the forge side: this pull's head commit lives in scout's fork, not in trevato/cs, and the forge may be failing to anchor the review to it. That is a guess I couldn't test. Someone with forge access needs to look at the review endpoint for cross-repo pulls, or post the review by hand. The approval text is in /tmp/r237f.json, outside the clone.
As last round, I couldn't check the preview itself: it answers 404, and so does production. I also couldn't open the screenshots because they're outside the clone. My clone is unchanged.
My review of pull #237 still isn't posted: this third round the forge again answered {"error":"bad_anchor"}, and the pull has no reviews. Resending the same request won't fix it, so I've stopped.
Likely cause: I changed the body in every way I could think of: with and without file paths and the short commit id, with an empty comments list, and with the head commit under five different field names. It fails the same way each time, so the text isn't the problem. My guess is the forge can't attach a review to this pull because its head commit, aeca800, is in scout's fork rather than in trevato/cs. I can't confirm that from here, and the forge has no API docs to check.
Verdict to post: approve. Names are escaped before they reach the page, and the in-match and final scoreboards share one ranking. The client still builds for the browser, and the two affected test files pass at the head. It notes two small fixes that shouldn't block it:
BoardRow.moneyis filled in but never shown.- The pull description starts with a stray "Pushed. Here's the pull description:" line.
Not checked: the preview answers 404, and so does production. The screenshots are outside the folder my tools can read. The final board only appears after a full match anyway.
Needed from a person: someone with forge access should look at why reviews fail on pulls from a fork, or paste the approval in by hand. The text is in /tmp/r237f.json. My clone is unchanged.
Pushed. Here's the pull description:
The match-over screen now shows the full final board instead of hiding it behind four lines.
finalBoard(world)(src/client/summary.ts, besidesummarize) turns the world into both sides' rows — ranked by kills then damage, the person's row marked withmine— andfinalBoardHtmlrenders that as two real<table>s with a caption per side, escaping names. It's built once when the match ends and dropped into a new#summary-boardcontainer with a singleinnerHTML, never redrawn per frame.hud.ts's in-match scoreboard now imports and calls the samerankPlayersexport instead of its own inline sort, so there's one ordering of the ten players in the repo — I left the rest ofhud.tsuntouched given #120/#183 are both holding it.escape()moved out ofsrc/pages/game.tsinto a new dependency-freesrc/escape.ts: the board's markup has to be built in the browser (only the client'sWorldhas all ten players' stats), andgame.tsimports../db.ts(realbun:sqlite) at the top level, which can't be bundled for a browser target — I confirmed this breaksBun.buildbefore picking this fix.game.tsre-exportsescapesoserver.ts's import is unchanged. Because of that same bundling constraint, the escaping/ranking tests for the new functions live insummary.test.tsrather thangame.test.tsas the issue suggested;game.test.tsstill gets its own direct test ofescape()plus a check that the SSR page carries the empty#summary-boardskeleton in the right place.CSS gives the board a capped height (
min(30vh, 15rem)) with its own scroll and a fixed table layout with a truncating name column, so it fits 360px with no horizontal scroll, never grows the overlay, and the#again/#summary-menubuttons stay reachable on a phone in landscape.Not done: no visual/browser testing was possible in this sandbox —
bun run check(tsc + all 858 tests) passes, and I manually renderedfinalBoardHtmloutput to confirm escaping, sort order and theminemarker.Closes #195