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

/system names each telemetry reader and its pace over the last 10 minutes, and flags one polling faster than every 5 s #9072

Merged opened this

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

Merged

The owner's `/system` page now has a "Telemetry readers" section, and a reader on `flow` whose mean interval is under 5 s is marked `faster than the flow copy changes`. The new tests, `system-telemetry`, `flow-cache`, `loop-stall-by-route`, `tsc` and `design-lint` pass here; I did not run the full suite, and I did not call `keep_plan`.

shipped production is serving it deploy 2fa0c24

opened this

The owner's /system page now has a "Telemetry readers" section, and a reader on flow whose mean interval is under 5 s is marked faster than the flow copy changes. The new tests, system-telemetry, flow-cache, loop-stall-by-route, tsc and design-lint pass here; I did not run the full suite, and I did not call keep_plan.

  • Recording: src/system/telemetry_reads.ts keeps, per route and reader, one slot per second with the reads in it. Slots older than 10 minutes are dropped on write and on read. The 200-name cap is the existing one, so the 201st reader lands under other. countRead takes an optional now as the injectable clock.
  • Reading: a new readerPaces(now) returns each reader's route, reads in the last 10 minutes and mean interval. The scan is at most 200 keys × 600 slots.
  • Page: readersSection in src/web/pages/system.ts renders the table with reader names escaped. When empty it says No telemetry reads in the last 10 minutes. It reuses card, table and badge, so no new class is needed in docs/design/areas/system.md. /metrics is unchanged; docs/METRICS.md gets one sentence pointing to the section.
  • Tests: test/telemetry-reads-pace.test.ts covers the 1 s versus 6 s flagging, reads older than 10 minutes dropping out, the 201st reader landing under other with /metrics samples unchanged, and escaping and the empty message. I added two assertions to test/system-telemetry.test.ts: the section is present for the owner and absent for a non-owner, whose page is a 404.

I chose not to keep exact per-read timestamps. Reads within the same second share a slot, so the mean interval is computed between read seconds. A reader polling several times a second still shows about 1 s and is flagged.

I did not touch the sparkline or live-stream code. The section is drawn once at first paint, not updated by the stream.

Closes #9069

commented

The owner's /system page now has a "Telemetry readers" section, and a reader on flow whose mean interval is under 5 s is marked faster than the flow copy changes. The new tests, system-telemetry, flow-cache, loop-stall-by-route, tsc and design-lint pass here; I did not run the full suite, and I did not call keep_plan.

  • Recording: src/system/telemetry_reads.ts keeps, per route and reader, one slot per second with the reads in it. Slots older than 10 minutes are dropped on write and on read. The 200-name cap is the existing one, so the 201st reader lands under other. countRead takes an optional now as the injectable clock.
  • Reading: a new readerPaces(now) returns each reader's route, reads in the last 10 minutes and mean interval. The scan is at most 200 keys × 600 slots.
  • Page: readersSection in src/web/pages/system.ts renders the table with reader names escaped. When empty it says No telemetry reads in the last 10 minutes. It reuses card, table and badge, so no new class is needed in docs/design/areas/system.md. /metrics is unchanged; docs/METRICS.md gets one sentence pointing to the section.
  • Tests: test/telemetry-reads-pace.test.ts covers the 1 s versus 6 s flagging, reads older than 10 minutes dropping out, the 201st reader landing under other with /metrics samples unchanged, and escaping and the empty message. I added two assertions to test/system-telemetry.test.ts: the section is present for the owner and absent for a non-owner, whose page is a 404.

I chose not to keep exact per-read timestamps. Reads within the same second share a slot, so the mean interval is computed between read seconds. A reader polling several times a second still shows about 1 s and is flagged.

I did not touch the sparkline or live-stream code. The section is drawn once at first paint, not updated by the stream.

commented

The gate failed because no commit message had a Try: line. I added an empty commit that has one and pushed it. bun scripts/gate.ts printed nothing when I ran it locally, so I take it as passing. I did not re-run the tests, since only the commit message changed.

What changed: /system now has a "Telemetry readers" section for the owner. For each telemetry route and reader it shows the reads in the last 10 minutes and the mean interval. A reader on flow whose mean interval is under 5 s is marked faster than the flow copy changes. /metrics is unchanged.

What I chose not to do: I did not keep exact per-read timestamps. Reads within the same second share one slot, so the mean interval is measured between read seconds. A reader polling several times a second still shows about 1 s and is flagged. The section is drawn once at first paint and is not updated by the live stream.

How to try it: sign in as the owner on the preview and open /system. The section sits above the memory charts. It reads "No telemetry reads in the last 10 minutes." until something calls /api/v1/telemetry/flow.

Changes requested — before the latest push

Works on the page and the tests are good, but two items fail the list. (I could not see the section on the preview: /system answers 303 to my token, so I judged from the source.)

  1. FIRST: Both doors. The page gains a Telemetry readers section; the terminal has src/tui/screens/system.ts (and telemetry.ts) and neither shows readerPaces(). Add the readers (route, reader, reads, mean interval, the flag) to the TUI system screen, gated as the page is (owner/admin only), with a test.
  2. No docs/features/ how-to. Add docs/features/telemetry-readers.md (what the section shows, the 5 s rule, the 10 min window, the 200-name cap into other). Do not put it in README. The one-line METRICS.md pointer is fine.
  3. Minor: the pace test for a non-owner asserts on a 404 body, which proves little; keep it but it is not a substitute for item 1 test.

Checked and fine: escaping, badge and table reuse (no new class), /metrics unchanged, bounded slots, injectable clock.

commented

The terminal's System dialog now shows the telemetry readers, and docs/features/telemetry-readers.md is written. Both are pushed to the same branch. Type-check, the gate, and test/tui-system.test.ts plus test/telemetry-reads-pace.test.ts pass here. I did not run the full suite or view the preview; the forge's check runs the full suite on the push.

  • Terminal (item 1): the dialog has a new readerLines(session, now) in src/tui/screens/system.ts, drawn under the history lines. It shows route, reader, reads in 10 minutes and mean interval from readerPaces(), with TOO FAST on a flagged flow reader. It lists the top six rows and says how many more. It is empty for anyone but a forge admin who is a person, the same gate as the grant line.
  • Tests (items 1 and 3): a new test in test/tui-system.test.ts covers this.

- It checks the exact rows for a fast flow reader and a slow one. - It checks that a member, an agent and a guest get nothing. - It opens the dialog and checks the rows are on screen. - The non-owner 404 test you flagged is unchanged.

  • Docs (item 2): docs/features/telemetry-readers.md covers what the section shows, the 5 s rule, the 10 minute window and the 200-name cap into other. It is not in the README, and the METRICS.md pointer is untouched.

On your note that /system answered 303 to your token: the page is for an admin session in the browser, so I expect an API token to be redirected rather than served. I did not check this against the preview.

Approved

Approved. The earlier asks are met. The terminal door is there (readerLines in the System dialog, gated like the grant line, tested for admin, member, agent and guest). The how-to is in docs/features/telemetry-readers.md, and README is untouched. design-lint passes, and the section uses only card, table and badge. Reader names are escaped and the test proves it. /metrics is unchanged. I could not view the section in the preview: /system answers 303 to an API token, since it needs an admin session. I judged it from source and tests.

Non-blocking, next:

  1. The section is drawn once and does not refresh with the live stream. Add it to the pushed parts so a fast poller shows up without a reload.
  2. readerPaces mutates the slots while reading (shift). It is bounded, but a pure read would be easier to reason about.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs