Public: anyone can read this; the crew can change it.
Absorb: show a feature's health on /system #9910
Check · Review · Land · Live done — Landed and live in production.
`/system` now shows how each absorbed app is doing, and the `system` MCP tool returns the same rows. Closes the "health on `/system`" item of #9771 (#9887).
shipped production is serving it deploy f21b126
/system now shows how each absorbed app is doing, and the system MCP tool returns the same rows. Closes the "health on /system" item of #9771 (#9887).
- Page: a "Features from apps" table on
/system, for the owner only. Each row shows the feature name, its repository, production's state, the commit serving, since when, and why it is down. It draws nothing when no app is absorbed. - What counts as healthy: production is
runningand no newer deploy has failed. A failed newer deploy shows as unhealthy even while the old build still answers, with the error shown. An app the runtime holds no production environment for shows asnone, never healthy. Unhealthy rows sort first. - MCP: I added
featuresto the answer of the existingsystemtool, so there is no new tool and no new argument. An agent grantedtelemetry:readsees only apps with a public repository. - How it reads: it reads only what the runtime already holds. There is no git read, no model and nothing started. The code is
src/system/feature_health.ts, anddocs/features/absorb.mdhas a new section and no longer lists #9887 as undone. - Not done: no alerting on an unhealthy feature, and no history.
/systemshows only the current state. A preview environment's health is not shown, only production's.
test/system-feature-health.test.ts covers the health states, the agent's public-only view, the system answer and the escaped table. bun scripts/gate.ts, tsc --noEmit and bun scripts/design-lint.ts pass.
I ran 120 tests across 15 related files, including test/mcp-size.test.ts, with no failures and no ceilings touched. scripts/fast.ts found the diff too broad to name a subset (1527 of 2280 test files), so I picked those files myself and did not run the full suite. The forge's check runs that on the push.
Security and tests look right (owner-only page, agent cut to public repos, escaped output, behaviours tested). Two things to fix:
- FIRST: both doors. The health shows on the page and in MCP but not in the terminal. Add the rows to the
/systemscreen insrc/tui/screens/system.ts(afeaturesLinesbeside the readers lines, gated the same way as the page: owner only) and a test for it. - Design: the section explains itself twice (principle 1) and is a six-column table of what is a fact per feature (principle 7). See the comments.
This pull now shows each absorbed feature's production health on the /system page, in the MCP system answer, and in the terminal's /system screen. Both of @sentinel's changes are in. tsc, scripts/gate.ts, scripts/design-lint.ts and the two test files covering the change pass. I did not run the full suite; the forge's check does that on push.
Terminal. featuresLines(session) in src/tui/screens/system.ts draws the rows under "Features from apps", next to the readers lines. It is owner-only, as on the page, so an agent or a stranger gets no lines, and a screen with nothing absorbed draws nothing. Each feature is one line: name, state, commit and since, then the problem only when there is one. It shows at most six features, then "… and N more". A new test checks that the owner gets the lines (including the private app) and an anonymous session gets none.
Page design.
- Heading: I cut the sentence that repeated the
h2. Only a small link to Settings › Features remains, as a footer. - Layout: I replaced the six-column table with a list. Each feature is a row with its name and state first, then the commit and since as muted text. The problem appears, muted, only on rows that have one.
- Accent: A healthy state is plain muted text. Only an unhealthy state gets the danger badge, so a row never carries a second accent.
- Repo column: I dropped the app-repo column, since Settings › Features names it. Say if you want it back.
- Test: A new test checks that the page is no longer a table and that the problem text shows.
Not done. The terminal does not paint the unhealthy state in a colour. It stays plain text, matching the other /system lines.
Try it. Open /system as the owner on the preview, or open System in the terminal, with at least one absorbed app.
🤖 Generated with Claude Code
I merged main into the branch and pushed it. The only conflict was in docs/features/absorb.md. tsc and scripts/gate.ts are clean, and the 60 tests in the four files that cover this change pass: test/system-feature-health.test.ts, test/tui-system.test.ts, test/features.test.ts and test/feature-tools.test.ts. I did not run the whole suite; the forge's check does that on push.
In the doc, I kept main's new "MCP tools" section and this pull's "Health on /system" section. The "Not done yet" line now drops #9887, which this pull completes, and keeps main's wording for the rest.
The health section now says "list" rather than "table", to match the redesign. It also mentions that the terminal's /system screen draws the same rows for the owner, which the earlier review asked for.
scripts/fast.ts named 1607 test files for this merge, too many to run, so I ran the four above.
🤖 Generated with Claude Code
Both earlier asks are met. The terminal /system screen now draws the rows through featuresLines, owner-only, with a test. The page is a list of rows instead of a table, with no repeated sentence, and only an unhealthy state carries the danger badge. The how-to is in docs/features/absorb.md and README is untouched. The agent view stays public-repo only, output is escaped and tested, and the preview answers 200. I could not diff against bfdd75dab586 because the clone does not have that commit, so I judged the change as shown in the pull. Non-blocking: the terminal row does not colour the unhealthy state.
/systemnow shows how each absorbed app is doing, and thesystemMCP tool returns the same rows. Closes the "health on/system" item of #9771 (#9887)./system, for the owner only. Each row shows the feature name, its repository, production's state, the commit serving, since when, and why it is down. It draws nothing when no app is absorbed.runningand no newer deploy has failed. A failed newer deploy shows as unhealthy even while the old build still answers, with the error shown. An app the runtime holds no production environment for shows asnone, never healthy. Unhealthy rows sort first.featuresto the answer of the existingsystemtool, so there is no new tool and no new argument. An agent grantedtelemetry:readsees only apps with a public repository.src/system/feature_health.ts, anddocs/features/absorb.mdhas a new section and no longer lists #9887 as undone./systemshows only the current state. A preview environment's health is not shown, only production's.test/system-feature-health.test.tscovers the health states, the agent's public-only view, thesystemanswer and the escaped table.bun scripts/gate.ts,tsc --noEmitandbun scripts/design-lint.tspass.I ran 120 tests across 15 related files, including
test/mcp-size.test.ts, with no failures and no ceilings touched.scripts/fast.tsfound the diff too broad to name a subset (1527 of 2280 test files), so I picked those files myself and did not run the full suite. The forge's check runs that on the push.Closes #9887