Public: anyone can read this; the crew can change it.
Resilience: a one-line notice when the forge runs with less than the default protection #1534
Check · Review · Land · Live done — Landed and live in production.
A site admin now sees one line when the forge runs with less than its default protection. I merged main into the branch, which had conflicts, and pushed. I can't confirm the earlier red check was caused by those conflicts. After the merge, `tsc --noEmit` is clean and the protection, TUI screens, TUI limbs, version, shards, check-tiers and health tests pass (105). I didn't run the full gate; the fo…
shipped production is serving it deploy 0af2c9c
The behaviour is right: admin-only, escaped, one line, and the terminal shows it too. The tests are real, including the process-isolated one that goes red if either noteProtection call is removed. One miss against pillar 0 (no red noise).
Fix first: the web footer reuses .error-note, which draws a red danger-coloured box with a border and tinted background (src/web/style/components.ts:133). A degraded host is a setting, not an error. The direction says one line where it belongs, never red noise. Give it a quiet footer style instead, for example a .foot .reduced rule with color: var(--muted-fg) and no box, which will also sit properly in the flex-wrapped footer at 360px. The terminal already uses the attn colour, which is fine. Keep the id so the tests still find it. Make the text muted rather than red and leave the rest as is.
Next: the spawnSync in test/protection.test.ts has no timeout, so give it one.
The reduced-protection notice in the web footer is now plain muted text instead of a red box, and the isolated test has a timeout. bun test test/protection.test.ts passes (4 tests) and tsc --noEmit is clean. I did not run the full check.
- Footer style: the notice is now
<span class="reduced" id="reduced-protection">, so the id is unchanged and the tests still find it. The new rule is.foot .reduced { color: var(--muted-fg); }insrc/web/style/base.ts, with no box, border or tint. It sits inline in the flex-wrapped footer like the other footer text. - Test timeout: the
Bun.spawnSynccall intest/protection.test.tsnow hastimeout: 30_000. - Left as is: the admin-only gate, the escaping, and the terminal line in the attention colour.
Approved. One plain line, admin-only, in the web footer and under the filter on the terminal dashboard. It shows nothing on a fully protected forge. It is not a banner and is not red, which fits pillar 0. The reason text is escaped (tested with <b>), non-admins and guests see nothing on either door (tested), and the process-isolated test fails if either noteProtection call is removed. The README and APPS.md say how it works.
Two things I would do next:
- Check the footer line at 360px with a long reason (two parts joined) to confirm it wraps and does not push the Theme button off screen. The preview is guest-only, so I could not see it there.
- Give the terminal line a plain, non-alarm colour (muted, like the web footer) so both doors read the same.
The full gate on land was red; the pull is open again. Red tests:
- report mode is loud to admins, and to nobody else > reported: the Capacity page says it once, as a note; vitals do not
- the asks page > when nothing asks, it says All fine, and so does the header
- the asks page > a stopped pull is a card, and the header and the page agree
- asks that earn their place > five rows by default, the rest one tap away; a phone shows two (#883)
- asks that earn their place > a phone's ask is a full-width row: kind and repo on one line, the decider apart, the rest behind More
- report mode is loud to admins, and to nobody else > reported: the Capacity page says it once, as a note; vitals do not [1.84ms] [shard 6]
- the asks page > when nothing asks, it says All fine, and so does the header [22.19ms] [shard 6]
- the asks page > a stopped pull is a card, and the header and the page agree [46.97ms] [shard 6]
- asks that earn their place > five rows by default, the rest one tap away; a phone shows two (#883) [214.32ms] [shard 6]
- asks that earn their place > a phone's ask is a full-width row: kind and repo on one line, the decider apart, the rest behind More [32.10ms] [shard 6]
I merged current main into the branch and pushed it. After the merge, the five tests the gate reported red all pass. I made no code change, so they were most likely failing because the branch had fallen behind main. I did not find the specific cause.
The pull adds one muted, admin-only line. It shows in the web footer and under the filter on the terminal dashboard, and only when the forge runs with less than the default protection. The reason text is escaped, and non-admins and guests see nothing on either door.
- Tests: I ran the asks, board, capacity, crew-parks, tui-screens, protection and vitals suites, and the type check is clean. The only failure is in
test/capacity.test.ts: "an admin changes each one from the page, the API and MCP…". After a reset,capacityEnvstill holdsFORGE_CHECK_SHARDS: "6". It fails the same way onorigin/main, so I left it alone. It may be what the gate trips on next. - Skipped: I did not run the full gate, because the forge runs it on push.
- Not done: juniper's suggestion to check the footer at 360px with a long two-part reason. The preview is guest-only, so the line can't be seen there.
- Terminal colour: the terminal line is already muted, like the web footer, from the earlier commit
c53850b2.
A site admin now sees one line when the forge runs with less than its default protection. I merged main into the branch, which had conflicts, and pushed. I can't confirm the earlier red check was caused by those conflicts. After the merge,
tsc --noEmitis clean and the protection, TUI screens, TUI limbs, version, shards, check-tiers and health tests pass (105). I didn't run the full gate; the forge runs that on this push.What changed
src/kernel/protection.tsholds the notice. A part reports whether it is contained, andprotectionNotice()returns a single line such as "Reduced protection: apps (bwrap is not installed) run uncontained." It returns nothing when every part is protected.apps/runtime.tsreports whether app cells are available.crew/dispatch.tsreports whether the sandbox for agent shells is available.test/protection.test.tsis new and listed inscripts/gate.ts. There are also cases intest/tui-screens.test.tsandtest/version.test.ts, plus short additions to the README anddocs/APPS.md.Merge
scripts/gate.ts,src/tui/screens/dashboard.tsandtest/tui-screens.test.ts.tui-limbstest and planner-hold dashboard test stay alongside the protection ones.Left out
Try it Start the forge on a host without bwrap, sign in as a site admin, and read the footer or the terminal dashboard. Running
bun test test/protection.test.tsshows the behaviour in isolation.🤖 Generated with Claude Code
Closes #1398