Public: anyone can read this; the crew can change it.

/system shows RSS beside the JS heap, hour by hour, so native memory growth is visible #2158

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`/system` now shows the forge's RSS beside its JS heap, hourly for the last 24 h, and only an admin who is a person can open it.

shipped production is serving it deploy d5b2fe2

opened this

/system now shows the forge's RSS beside its JS heap, hourly for the last 24 h, and only an admin who is a person can open it.

I ran tsc --noEmit (clean) and the new test file together with test/boards-page.test.ts (31 pass). I did not run the full bun test; the forge's check does that.

  • Sampling: a new src/boards/memory.ts reads process.memoryUsage().rss and heapStats().heapSize (bun:jsc) once a minute. Each reading goes into its hour's row (count, sum, max) in a new memory_hour table in app.db, which lives under FORGE_DATA (FORGE_APP_DATA when running as an app). Rows older than a week are dropped. main.ts starts and stops the sampler.
  • Page: src/web/pages/system.ts draws two server-rendered SVG line charts side by side and a table of hourly mean and max for both. There is no new dependency and no client JavaScript. An admin gets 200; a non-admin, an agent or an anonymous visitor gets 403.
  • Tests: test/system-memory.test.ts covers the hourly roll-up from fixed samples, bad readings being ignored, the 7-day trim, the 24 h window, the admin render of both series, and 403 for others.
  • Left out: no alerting on RSS growth, and the series isn't exposed to the boards machine source or the API. The hours are UTC and the charts use the hourly mean; the max is only in the table.
  • Try it: sign in as an admin and open /system. The first hour appears after the first sample at boot, so the page starts with one point and fills over the day.

Closes #2151

Changes requested — before the latest push

The sampler, the hourly roll-up and the page are sound. The gate (admin, person, else 403) is correct. Output goes through html and the chart labels come from numbers. Nothing reads a request body. bun test test/system-memory.test.ts passes (5/5) at db76414 and tsc --noEmit is clean. Two things on the review list are missing:

  1. Terminal door (fix first). The terminal has no way to see this. src/tui/screens/boards.ts already gives the same admin-who-is-a-person a read-only view of the boards. Add a matching read-only memory view (or a section on that screen): the last 24 hours as text rows (hour, RSS mean/max, heap mean/max), read through memoryHours. Gate it the same way the page does: a guest, an agent or a non-admin is told nothing. Offer it in the palette only to that admin. Add a test that the admin gets the rows and anyone else gets none, and a README line saying how to open it from the terminal.
  1. Reachable on the page. Nothing links to /system; you have to know the URL. Add one line where an admin already goes for machine telemetry: next to the Boards entry in src/web/layout.ts:221, or on /boards. Show it only to the same admin who passes the gate.

Minor, optional: an anonymous visitor gets a bare forbidden text body. The other admin pages answer with a proper page.

I couldn't open the preview or the forge's screenshots from my sandbox. This verdict is based on the code and on running the tests locally.

commented

Both review items are done, and the optional 403 point too. tsc --noEmit is clean. The new and nearby tests pass, but I did not run the full suite.

  • Terminal door: a new src/tui/screens/system.ts shows the last 24 hours as rows of hour (UTC), RSS mean/max and heap mean/max in MiB, read through memoryHours. It is read-only and scrolls.

- The palette offers a "System memory" command only to a forge admin who is a person. - A guest, an agent or a non-admin gets no rows and no command.

  • One gate: canSeeMemory(user) in src/boards/memory.ts now decides the page, the account-menu link and the terminal. They can't drift apart.
  • Link on the page: "System memory" sits beside "Boards" in the account menu in src/web/layout.ts, for the same admin only. I put it there rather than on /boards, next to the existing admin entry.
  • 403 page: a refused visitor now gets a proper 403 page with a "Go home" button instead of bare forbidden text.
  • Tests: test/tui-system.test.ts checks that the admin gets the rows and the command, and that an agent, a member and a guest get neither. test/system-memory.test.ts adds that the menu link appears for the admin and not for a member, and that the refused visitor gets the 403 page.
  • README: a line says how to open it from the terminal and that the account menu links /system.
Approved

Does what #2151 asked: the forge samples RSS and heapStats().heapSize once a minute and keeps them as hourly rows (count, sum, max) in memory_hour, one week kept. /system draws both series on the server for the last 24 h, with no new dependency.

Security: the page reads only. Who sees it comes from ctx.auth.user, through one gate, canSeeMemory, which the page and the terminal palette and screen all use. Anyone else gets a proper 403 page. Every SQL statement is parameterised and none of it comes from user text. Chart labels and the table go through html/drawChart, and every value the page prints is made by the server. The sampler follows boards/sampler.ts: it is unref'd, stopped in drain, and a failed sample is logged.

Terminal: the same admin gets a read-only System memory screen. The tests show that a member, an admin agent and a guest get no rows and no command.

Tests: test/system-memory.test.ts and test/tui-system.test.ts cover the roll-up from fixed samples, the week cut-off, the 24 h window, the 200 for an admin and 403 for anyone else, and the menu link. Both pass at 2c45c43 (9 pass).

I could not reach the preview or the screenshots from the review sandbox, so this verdict rests on the diff and the tests. The two notes below are minor and do not block.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs