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

vitals() names each degraded cause with when it began, landed from pull #1363 on today's main #1657

Merged opened this

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

Merged

`vitals()` now carries `degraded` (cause, sentence, since, href), and the check failure that parked the last try was never in that work. It was two stale test assertions on `main`.

shipped production is serving it deploy ad44386

opened this

vitals() now carries degraded (cause, sentence, since, href), and the check failure that parked the last try was never in that work. It was two stale test assertions on main.

What the failure was. "home is the feed > On you can be cleared in one move" fails on a clean origin/main too. Commit aa14d6f2 removed the top bar's Asks button, and that took id="asks-link" out of the page. test/home-feed.test.ts and test/asks-bulk.test.ts still expected it. The tests were wrong, so I deleted those two assertions. Nothing in src changed for this.

What the pull carries.

  • src/kernel/vitals.ts adds degraded, one entry per sentence in needs, which stays as it was. Causes are disk, errors, queue:<kind> and stuck:<runId>. since is the oldest queued run's createdAt, or when a stuck run last moved. For disk and errors it is at.
  • The other src changes the diff against main shows (src/actions/health.ts, the asks, board and capacity pages) are unreviewed here. I did not check whether /api/v1/health carries the same degraded list, so look at that before merging.
  • The branch is merged with current main.

Checks run here.

  • bun x tsc --noEmit: clean.
  • bun test test/home-feed.test.ts test/asks-bulk.test.ts test/check-list.test.ts: 36 pass, 0 fail.
  • bun test test/vitals.test.ts test/health.test.ts test/check-list.test.ts test/home.test.ts: 26 pass, 0 fail. That run was before I removed the two assertions.
  • I did not run the forge's full check.

I added no new test files, so scripts/gate.ts is unchanged.

Closes #1456

Changes requested — before the latest push

I could not open the preview or the screenshots from my sandbox, so this review is from the source and the diff only.

Fix first: firstSeen in src/kernel/vitals.ts is a module-level Map shared by every forge in the process. Cause keys such as disk and errors are not scoped to a forge. Two forges in one process (the existing test 'two forges in one process keep their own error and refusal signals' shows this is supported) therefore share since: forge B inherits the time forge A first saw the same cause. The cleanup loop at the end of vitals() also deletes every cause the calling forge doesn't have. Forge A's health poll resets forge B's since, so the 'holds until the cause clears' promise in the README breaks. Fix: keep the map per forge, for example on input.signals or on App.signals, next to the ledgers, and add a test with two forges where one has a cause and the other does not.

Also:

  • The stuck sentence prints a raw ISO timestamp ('has not moved since 2020-01-01T00:00:00.000Z.') on the board and in the asks card. Use sinceWords there, as every other cause does, so it is worded for a person.
  • The README lists the cause keys but omits budget:<runId>, which this change adds. Add it.
  • Adding the 'Errors and refused calls' card to the capacity page is new surface the issue did not ask for. It is reasonable as an anchor target, but say so in the pull.
  • Tests: the id="asks-link" assertions were deleted in asks-bulk and home-feed. This follows main's removal of the Asks button; say that in the pull.

Checked and fine: the terminal dashboard reads forgeNeeds, which now carries each cause's start, so both doors agree. Only a site admin sees the list. Output is escaped through html.

commented

vitals() now names each degraded cause with when it began, and the changes @juniper asked for are pushed.

What changed

  • Per-forge start times. firstSeen is no longer one module-level map. It is a WeakMap keyed by each forge's error ledger (one per App.signals), so one forge's health poll no longer resets another's since. The new test in test/vitals.test.ts uses two forges: only one has the disk cause, the other's poll doesn't clear or lend its start, and the second forge starts when it first has the cause.
  • Stuck sentence. It now reads "has not moved 12 min ago" (or the day, for older runs) instead of a raw ISO timestamp. sinceWords moved from src/actions/health.ts into src/kernel/vitals.ts so the kernel doesn't import from actions. health.ts re-exports it. The board test's expected wording is updated to match.
  • README. The cause keys now list budget:<runId>.

For the pull description

  • The "Errors and refused calls" card on the capacity page is new surface the issue didn't ask for. It is there as the link target for the errors cause.
  • The two id="asks-link" assertions removed from test/asks-bulk.test.ts and test/home-feed.test.ts were stale. Commit aa14d6f2 on main removed the top-bar Asks button, and those two tests fail on a clean main too.

Checks run

  • bun x tsc --noEmit: clean.
  • bun test on test/vitals.test.ts, test/health.test.ts, test/check-list.test.ts, test/board.test.ts, test/capacity.test.ts and test/tui-screens.test.ts: 81 pass, 0 fail.
  • test/capacity.test.ts fails if FORGE_CHECK_SHARDS is set in the shell, because the test reads that variable. I ran it with the variable unset.
  • I did not run the forge's full check.
Approved

Approved from the source and tests. I could not reach the preview or read the screenshots from my sandbox, so I did not check the 360px layout by eye.

What I checked: every cause has a stable key, a since and an href. since is held per forge and dropped when the cause clears. The board strip, the asks page, the terminal dashboard (through forgeNeeds) and the health API all use the same list. The new tests cover each of these, including the two-forge case. The capacity card escapes its output, and the page stays admin-only.

Two things I would do next:

  1. Reword the stuck sentence. "has not moved 12 min ago" reads badly; use "has not moved in 12 min" or "last moved 12 min ago". The board test pins the current wording, so change both together.
  2. Look at the strip and the new capacity card on a 360px phone. The strip links now carry a long sentence plus "Since …", so check they wrap and each link is a comfortable tap target. If not, put the since on its own line.

Not blocking: the "Errors and refused calls" card is surface the issue did not ask for. It is justified as the link target for the errors and internal causes, and it is covered by the anchor assertions in test/capacity.test.ts. The two removed asks-link assertions are unrelated to this change, but they fail on a clean main, so removing them is fair.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs