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

The terminal lists who can do what in each app, read from its contract.json, as /audit and MCP `audit` do #7946

Merged opened this

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

Merged

The terminal now has a "Who can do what" screen, offered in the palette to everyone, signed in or not. It is the terminal's version of `/audit` and MCP `audit`, and reads through the same `audit()` (`src/contract/audit.ts`) and the same visibility (`listReposVisibleTo`), so it never shows anything about a repository the viewer cannot read.

shipped production is serving it deploy fb6f20c

opened this

The terminal now has a "Who can do what" screen, offered in the palette to everyone, signed in or not. It is the terminal's version of /audit and MCP audit, and reads through the same audit() (src/contract/audit.ts) and the same visibility (listReposVisibleTo), so it never shows anything about a repository the viewer cannot read.

  • src/tui/screens/audit.ts (new): one row per app with its name and standing. The standing is one of "unread" (no contract.json; listed, never hidden), "unsound: N problems", "closed to strangers" or "N doors open to anyone". Each row also says whether outsiders may direct the app's crew, from crewOutsiders, as MCP audit reports it. Under the list, the selected app shows each resource.verb with yes, own or no for each identity; for an unsound or unread app it shows why there is no table. Enter opens the app's repository screen, as the other lists do.
  • src/tui/screens/entries.ts: one line adds the entry, after access.
  • test/tui-audit.test.ts (new): a reader sees their own apps, including the private one, with doors; a stranger sees only the public apps; an app without a contract reads "unread"; the palette offers the screen, the screen draws, and Enter opens the repository.
  • test/palette-roster.test.ts: this test was not wrong; it lists every palette entry for each kind of viewer, so the new entry is added there, one line in each of its four rosters.

Left out: the page's probe knock, contract history, pulls waiting at the wall and the CSV export stay on /audit. No MCP tool was added or changed.

Checks run: bun scripts/gate.ts and bun x tsc --noEmit are clean. scripts/fast.ts named 236 test files (about 19 minutes), so I ran the ones that cover this change instead, and they pass: tui-audit, palette-roster, palette-entries, tui-screens, tui-size, tui-first, outsider-tty, strangers, audit, xss-everywhere and mcp-size. The forge's check runs the rest on this push.

To try it: in the terminal, press ctrl+k and type "Who can do what", then press Enter. Move between apps with the arrow keys, and press Enter on a row to open its repository.

🤖 Generated with Claude Code

Closes #7935

commented

The terminal now has a "Who can do what" screen, offered in the palette to everyone, signed in or not. It is the terminal's version of /audit and MCP audit, and reads through the same audit() (src/contract/audit.ts) and the same visibility (listReposVisibleTo), so it never shows anything about a repository the viewer cannot read.

  • src/tui/screens/audit.ts (new): one row per app with its name and standing. The standing is one of "unread" (no contract.json; listed, never hidden), "unsound: N problems", "closed to strangers" or "N doors open to anyone". Each row also says whether outsiders may direct the app's crew, from crewOutsiders, as MCP audit reports it. Under the list, the selected app shows each resource.verb with yes, own or no for each identity; for an unsound or unread app it shows why there is no table. Enter opens the app's repository screen, as the other lists do.
  • src/tui/screens/entries.ts: one line adds the entry, after access.
  • test/tui-audit.test.ts (new): a reader sees their own apps, including the private one, with doors; a stranger sees only the public apps; an app without a contract reads "unread"; the palette offers the screen, the screen draws, and Enter opens the repository.
  • test/palette-roster.test.ts: this test was not wrong; it lists every palette entry for each kind of viewer, so the new entry is added there, one line in each of its four rosters.

Left out: the page's probe knock, contract history, pulls waiting at the wall and the CSV export stay on /audit. No MCP tool was added or changed.

Checks run: bun scripts/gate.ts and bun x tsc --noEmit are clean. scripts/fast.ts named 236 test files (about 19 minutes), so I ran the ones that cover this change instead, and they pass: tui-audit, palette-roster, palette-entries, tui-screens, tui-size, tui-first, outsider-tty, strangers, audit, xss-everywhere and mcp-size. The forge's check runs the rest on this push.

To try it: in the terminal, press ctrl+k and type "Who can do what", then press Enter. Move between apps with the arrow keys, and press Enter on a row to open its repository.

🤖 Generated with Claude Code

Approved

Clean. The terminal screen uses the same visibility (listReposVisibleTo + appsForRepos, limit 200) and the same audit() as the /audit page, so a guest sees only public apps and nothing private leaks. It is read-only, so there is no write to gate. All output goes through the TUI widgets. Tests cover reader, stranger, unread, palette offer, paint and Enter. The roster test is updated, and the preview /audit answers 200. No new dependency. Minor nit, not blocking: the nested ternary for tone in auditRows would read better as a small helper.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs