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

Each row of docs/THREATS.md names the test or gate that enforces it, and a test fails on a row that names none #11874

Merged opened this

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

Merged

Every protection in `docs/THREATS.md` now ends in an `Enforced by:` line in place of the old `Test:` line. In the internal-calls table, the last column holds the enforcer. An enforcer is one of three things: - a test file under `test/` - a gate under `scripts/` - `none yet`, with an optional `(#N)` for the open issue that owns the gap

shipped production is serving it deploy 11ca711

opened this

Every protection in docs/THREATS.md now ends in an Enforced by: line in place of the old Test: line. In the internal-calls table, the last column holds the enforcer. An enforcer is one of three things:

  • a test file under test/
  • a gate under scripts/
  • none yet, with an optional (#N) for the open issue that owns the gap

No enforcer was added or changed: every row keeps the test file it already cited.

What moved where

  • src/core/threats.ts: parseThreats reads Enforced by:. The new enforcement(md, exists) checks the doc against the rule and returns plain data: the problems, the none yet count, and the cited paths. Bullets under a (later) heading are preconditions, not protections, so it skips them. The Protection.test field keeps its name but may now hold a scripts/ gate; such a row shows "untested" on the Resilience page, because no gate result ever names a script file.
  • test/threats-doc.test.ts → test/threats-enforced.test.ts: the test fails when a bullet has no Enforced by: line, a call row's last cell names nothing, a named path does not exist, an enforcer is neither a test, a gate nor none yet, or the old Test: form is still there. Each of these cases has its own fixture. It also checks that every row the Resilience page lists was judged, and prints threats: 5 rows enforced by none yet.
  • test/resilience.test.ts and test/checks-resilience.test.ts: these two tests changed. Their fixtures and line counts used the Test: form the issue retires, so they now use Enforced by:. Nothing else in them changed.
  • scripts/gate.ts picks up every test/*.test.ts by itself, so nothing needed adding there.

Follow-ups: the none yet rows (none filed by this pull)

  1. TLS at the edge: certificates are issued only for names the forge vouches for (the on_demand_tls ask).
  2. Traffic from the edge to the forge, and from the forge to a cell, is not encrypted.
  3. Revoking every token of one account at once, and telling its owner when a token is used from somewhere new.
  4. Reviewing lockfile (bun.lock) changes before they reach an app's cell.
  5. Distributed attacks across many addresses: only the whole-forge caps stand there.

The issues API has no search, so I couldn't find any existing open issues for these and cited no #N rather than guess one.

Checks run here

  • Passed: bun scripts/gate.ts, bun x tsc --noEmit, and bun test on test/threats-enforced.test.ts, test/resilience.test.ts, test/checks-resilience.test.ts, test/resilience-fit.test.ts and test/tui-screens.test.ts.
  • Skipped: the phone-layout check in resilience-fit skipped itself because no Chromium starts in this sandbox.
  • Not run: bun scripts/fast.ts named 1641 test files, because threats.ts is reached from the server, so I ran the tests above instead of all of them.

🤖 Generated with Claude Code

Closes #11865

commented

Every protection in docs/THREATS.md now ends in an Enforced by: line in place of the old Test: line. In the internal-calls table, the last column holds the enforcer. An enforcer is one of three things:

  • a test file under test/
  • a gate under scripts/
  • none yet, with an optional (#N) for the open issue that owns the gap

No enforcer was added or changed: every row keeps the test file it already cited.

What moved where

  • src/core/threats.ts: parseThreats reads Enforced by:. The new enforcement(md, exists) checks the doc against the rule and returns plain data: the problems, the none yet count, and the cited paths. Bullets under a (later) heading are preconditions, not protections, so it skips them. The Protection.test field keeps its name but may now hold a scripts/ gate; such a row shows "untested" on the Resilience page, because no gate result ever names a script file.
  • test/threats-doc.test.ts → test/threats-enforced.test.ts: the test fails when a bullet has no Enforced by: line, a call row's last cell names nothing, a named path does not exist, an enforcer is neither a test, a gate nor none yet, or the old Test: form is still there. Each of these cases has its own fixture. It also checks that every row the Resilience page lists was judged, and prints threats: 5 rows enforced by none yet.
  • test/resilience.test.ts and test/checks-resilience.test.ts: these two tests changed. Their fixtures and line counts used the Test: form the issue retires, so they now use Enforced by:. Nothing else in them changed.
  • scripts/gate.ts picks up every test/*.test.ts by itself, so nothing needed adding there.

Follow-ups: the none yet rows (none filed by this pull)

  1. TLS at the edge: certificates are issued only for names the forge vouches for (the on_demand_tls ask).
  2. Traffic from the edge to the forge, and from the forge to a cell, is not encrypted.
  3. Revoking every token of one account at once, and telling its owner when a token is used from somewhere new.
  4. Reviewing lockfile (bun.lock) changes before they reach an app's cell.
  5. Distributed attacks across many addresses: only the whole-forge caps stand there.

The issues API has no search, so I couldn't find any existing open issues for these and cited no #N rather than guess one.

Checks run here

  • Passed: bun scripts/gate.ts, bun x tsc --noEmit, and bun test on test/threats-enforced.test.ts, test/resilience.test.ts, test/checks-resilience.test.ts, test/resilience-fit.test.ts and test/tui-screens.test.ts.
  • Skipped: the phone-layout check in resilience-fit skipped itself because no Chromium starts in this sandbox.
  • Not run: bun scripts/fast.ts named 1641 test files, because threats.ts is reached from the server, so I ran the tests above instead of all of them.

🤖 Generated with Claude Code

Approved

Approved. Every row now ends in an Enforced by: line, and enforcement() in src/core/threats.ts is small, plain data in and out, and tested for each failure case. The old threats-doc test is folded into the new one, and the resilience fixtures were updated with it. No UI or dependency change, and no README addition. Next two things: (1) give the 5 none-yet rows an (#N) each, filed as separate follow-ups, and tighten NONE_YET to require it once they exist; (2) show scripts/ gate rows as enforced rather than untested on the Resilience page.

commented

Left #11865 open: 1 unticked item remain (Each threat in docs/THREATS.md carries one line Enforced by: <path> naming a test file or a gate in scripts/, or Enforced by: none yet (#N) with an open issue.).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs