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

Ops security page: one line per control and when it was last checked #10595

Merged opened this

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

Merged

The ops security page now lists one line per control in `docs/ops/RED-TEAM.md` with when it was last checked. It reads only evidence that already exists (`security-report.json` and check results) and follows the P9 Calm rules.

shipped production is serving it deploy 7ab3f87

opened this

The ops security page now lists one line per control in docs/ops/RED-TEAM.md with when it was last checked. It reads only evidence that already exists (security-report.json and check results) and follows the P9 Calm rules.

What was red. The page and its tests were fine. The earlier check failed on scripts/unreached-allow.json, which carried an allow-list entry for src/kernel/why_now.ts. That module no longer exists on main, so test/unreached.test.ts failed on the stale entry. I merged main into the branch and reset that file to main's version, which drops the entry.

What changed

  • src/web/pages/security_controls.ts (new) is the page.
  • src/web/pages/security.ts and src/http/settings_routes.ts hook it into the existing security page and route.
  • docs/design/audit.md has its audit entry. The Server-Timing phases are named on the page. The one-line edit to docs/ops/RED-TEAM.md is also in the diff.
  • test/security-controls.test.ts covers the page.

Checks run. bun scripts/gate.ts, bun x tsc --noEmit and bun scripts/design-lint.ts are clean. The tests I ran are green: security-controls, unreached, web-ui, plus the server-timing, design-audit, security and red-team suites. scripts/fast.ts exits 2 (the diff is too broad to name), so I picked those by hand rather than running the full suite. The forge's own check runs the full suite on this push.

Left out. No new storage and no new evidence source, and no edit controls. The page only shows what the report and check results already say.

To try it. Open the security page under ops in the pull preview.

Closes #10452

commented

The ops security page now lists one line per control in docs/ops/RED-TEAM.md with when it was last checked. It reads only evidence that already exists (security-report.json and check results) and follows the P9 Calm rules.

What was red. The page and its tests were fine. The earlier check failed on scripts/unreached-allow.json, which carried an allow-list entry for src/kernel/why_now.ts. That module no longer exists on main, so test/unreached.test.ts failed on the stale entry. I merged main into the branch and reset that file to main's version, which drops the entry.

What changed

  • src/web/pages/security_controls.ts (new) is the page.
  • src/web/pages/security.ts and src/http/settings_routes.ts hook it into the existing security page and route.
  • docs/design/audit.md has its audit entry. The Server-Timing phases are named on the page. The one-line edit to docs/ops/RED-TEAM.md is also in the diff.
  • test/security-controls.test.ts covers the page.

Checks run. bun scripts/gate.ts, bun x tsc --noEmit and bun scripts/design-lint.ts are clean. The tests I ran are green: security-controls, unreached, web-ui, plus the server-timing, design-audit, security and red-team suites. scripts/fast.ts exits 2 (the diff is too broad to name), so I picked those by hand rather than running the full suite. The forge's own check runs the full suite on this push.

Left out. No new storage and no new evidence source, and no edit controls. The page only shows what the report and check results already say.

To try it. Open the security page under ops in the pull preview.

Changes requested — before the latest push

Changes needed, in one round:

  1. Both doors: there is no screen in src/tui/ for this page, so an admin in the terminal cannot see the controls. Add one, with its entry where AGENTS.md says.
  2. Add docs/features/security-controls.md with the how-to, including the shape of the controls list in security-report.json. The one line in RED-TEAM.md is not a how-to.
  3. The page does not do what the issue asks. Nothing writes controls into security-report.json, so in production every line says "No check recorded" and the page shows no real rows (principle 2). Either record a check for each control (the test run or the red-team run writes {id, at, ok}), or take the time from an evidence source that already exists. The pod-security control can never be recorded as written.
  4. Tests: the "Out of date" badge and the 8-day boundary are untested, as is the new link on the security page. Each would fail without the behaviour only if it is tested.
  5. Design principles 1, 7 and 8, see the line comments.
commented

This round addresses all five points of the review. tsc, scripts/gate.ts and scripts/design-lint.ts pass. So do test/security-controls.test.ts, test/palette-roster.test.ts and 18 related test files (security, palette). I did not run the whole suite; scripts/fast.ts found the diff too broad to name tests, so I picked those files myself.

What changed

  • Terminal screen (1): admins get a "Security controls" palette command, with the screen in src/tui/screens/controls.ts and its entry in ENTRIES as AGENTS.md says. It shows the same rows as the page. I added the new entry to the admin roster in test/palette-roster.test.ts, which lists every admin command.
  • Docs (2): docs/features/security-controls.md covers the how-to and the shape of the controls list ({id, at, ok}). The RED-TEAM.md line now points to it.
  • Real rows (3): the five controls a test file keeps now take their time from the existing report's own at, passing when selfTest.failed is 0. That timer is already running, so existing reports give those rows a time with no new writer. An explicit controls entry still overrides it.
  • Pod security: it only gets a time if a controls entry names it. No test here can see the cluster, so it says "No check recorded" and I did not invent a check. Say if you'd rather drop it from the list.
  • Shared module: the list and the reading moved to src/checks/controls.ts, shared by the page and the screen.
  • Tests (4): new tests cover a 9-day check showing "Out of date" and a 7-day one not, the report-time fallback including a failing self-test, the link on /settings/security, and the terminal rows matching the page.
  • Design (5):

- The intro now reads "Each safeguard, and when it was last tested." - A row is the name plus its state (badge and time). The sentence and the test path moved to the name's title and the docs. - Failed and Out of date share one attn badge. - The Security page link is folded into its existing intro sentence instead of a second line.

Left out: I did not write controls entries from the test run or the red-team run, because that writer sits outside this repository. The 8-day staleness window is unchanged.

Approved

All earlier asks are met: a terminal screen with its palette entry and roster test, a docs/features how-to (README untouched), real times from the report with Pod security left honestly unrecorded, tests for staleness, fallback, link and terminal parity, and a tighter design (one attn badge, a dl of rows, intro folded into the Security page sentence). The page is admin-only (guest 303, non-admin 404), the file read is size-capped, and the output is escaped through html. Non-blocking: the page intro repeats the h1 and the Back link duplicates the settings nav; the web gate does not exclude agent users while the terminal does; the per-control description lives only in a title attribute, which is not visible without hover.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs