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

A test file outside `test/` runs in the gate: `src/apps/contain-label.test.ts` moves into `test/`, and the gate refuses a new `*.test.ts` under `src/` #11227

Merged opened this

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

Merged

I moved `src/apps/contain-label.test.ts` to `test/contain-label.test.ts` and pointed its import at `../src/apps/contain.ts`. It now lands in the gate plan, because the gate collects tests from `test/` only (`presentTests`). It passes in socket mode in about 1.6 s, well inside its per-file budget, so it needs no skip entry.

shipped production is serving it deploy f21b126

opened this

I moved src/apps/contain-label.test.ts to test/contain-label.test.ts and pointed its import at ../src/apps/contain.ts. It now lands in the gate plan, because the gate collects tests from test/ only (presentTests). It passes in socket mode in about 1.6 s, well inside its per-file budget, so it needs no skip entry.

scripts/gate.ts has a new strayTestRefusal. It walks src/ recursively and lists every *.test.ts outside any vendor/ directory, one line per file, e.g. gate: src/x.test.ts: a test outside test/ never runs in the gate; move it to test/. bun scripts/gate.ts runs it alongside the other refusals and exits 2 when it finds one.

test/gate-stray-test.test.ts builds a temporary tree with tests under src/, under src/vendor/ and under test/. It checks that only the src/ ones are named, sorted. A second test checks that this repository itself has none. Without the change the first test fails, because strayTestRefusal isn't exported.

Not done: the gate still doesn't run tests where they sit under src/. It refuses them instead, so test/ stays the only place tests live.

Checks run here: bun scripts/gate.ts passes, bun x tsc --noEmit is clean, and bun test passes on test/gate*.test.ts, test/check-list.test.ts, test/review-rules.test.ts and test/contain-label.test.ts. scripts/fast.ts exited 2 (the diff touches scripts/gate.ts, too broad to name tests), so I picked these test files myself.

To try it: add an empty src/x.test.ts and run bun scripts/gate.ts. It exits 2 and names the file.

🤖 Generated with Claude Code

Closes #11222

commented

I moved src/apps/contain-label.test.ts to test/contain-label.test.ts and pointed its import at ../src/apps/contain.ts. It now lands in the gate plan, because the gate collects tests from test/ only (presentTests). It passes in socket mode in about 1.6 s, well inside its per-file budget, so it needs no skip entry.

scripts/gate.ts has a new strayTestRefusal. It walks src/ recursively and lists every *.test.ts outside any vendor/ directory, one line per file, e.g. gate: src/x.test.ts: a test outside test/ never runs in the gate; move it to test/. bun scripts/gate.ts runs it alongside the other refusals and exits 2 when it finds one.

test/gate-stray-test.test.ts builds a temporary tree with tests under src/, under src/vendor/ and under test/. It checks that only the src/ ones are named, sorted. A second test checks that this repository itself has none. Without the change the first test fails, because strayTestRefusal isn't exported.

Not done: the gate still doesn't run tests where they sit under src/. It refuses them instead, so test/ stays the only place tests live.

Checks run here: bun scripts/gate.ts passes, bun x tsc --noEmit is clean, and bun test passes on test/gate*.test.ts, test/check-list.test.ts, test/review-rules.test.ts and test/contain-label.test.ts. scripts/fast.ts exited 2 (the diff touches scripts/gate.ts, too broad to name tests), so I picked these test files myself.

To try it: add an empty src/x.test.ts and run bun scripts/gate.ts. It exits 2 and names the file.

🤖 Generated with Claude Code

commented

A *.test.ts file under src/ now runs in the gate's test step: src/apps/contain-label.test.ts moves to test/contain-label.test.ts, and scripts/gate.ts now refuses any test file left under src/. test/gate-stray-test.test.ts tests that refusal.

Fix for the red check: test/plugin-claude-oauth.test.ts was also failing on main, separately from this change. #11193 added archive and undo to the /forge command list in plugins/claude-code/commands/forge.md, but did not add them to plugin.json's description. It also left the test checking for a fixed count of 10 verbs.

  • plugin.json's description and the plugins paragraph in docs/MCP.md now list all 12 verbs.
  • The test was the thing that was wrong, so it changed: instead of the count, it reads the verbs from the command's own ` - verb bullets and expects them to match the description:` line. Adding a verb now fails until the description lists it too.

Checks run: bun scripts/gate.ts and bun x tsc --noEmit pass. scripts/fast.ts couldn't pick the tests because scripts/gate.ts changed, so I ran the covering files myself and they pass:

  • the plugin tests
  • test/gate-stray-test.test.ts
  • test/contain-label.test.ts
  • the MCP doc/table tests (test/mcp-get, test/mcp-card-table, test/mcp-table, test/mcp-size)

🤖 Generated with Claude Code

commented

A *.test.ts file under src/ now runs in the gate's test step: src/apps/contain-label.test.ts moves to test/contain-label.test.ts, and scripts/gate.ts refuses any test file left under src/. test/gate-stray-test.test.ts tests that refusal.

This pull also fixes the Claude Code plugin's verb list, which #11193 left stale. /forge gained archive and undo, but plugin.json's description didn't list them and test/plugin-claude-oauth.test.ts still expected exactly 10 verbs. The description and the plugins paragraph in docs/MCP.md now list all 12 verbs. The test was what was wrong: it now reads the verbs from the command's own ` - verb bullets in plugins/claude-code/commands/forge.md and expects them to match its description:` line, so adding a verb fails until the description names it.

main has since fixed the same failure by changing the expected count to 12. The merge kept this branch's version, which checks the same 12 verbs and also fails when a 13th is added without being described. That one test was the only conflict; plugin.json and docs/MCP.md merged cleanly to the same wording.

After the merge, bun scripts/gate.ts and bun x tsc --noEmit pass. scripts/fast.ts can't narrow the tests down while scripts/gate.ts is in the diff, so I picked the covering files myself; all of these pass:

  • test/plugin-claude-oauth.test.ts
  • test/plugins.test.ts
  • test/gate-stray-test.test.ts
  • test/contain-label.test.ts
  • test/mcp-table.test.ts

🤖 Generated with Claude Code

Changes requested — before the latest push

The gate change is right: contain-label.test.ts moves to test/, strayTestRefusal names each stray *.test.ts under src/ (vendor excluded), and the test proves it. One thing to fix: the pull also carries unrelated work that issue #11222 did not ask for. It rewrites the verb check in test/plugin-claude-oauth.test.ts and reflows the plugins paragraph in docs/MCP.md. main already fixed that failure by changing the expected count to 12, and the direction asks for small single-purpose pulls. Restore both files to main's version, and open a separate issue if the stricter verb check is wanted.

commented

A .test.ts file under src/ now runs in the gate. src/apps/contain-label.test.ts moves to test/contain-label.test.ts, and scripts/gate.ts gains strayTestRefusal, which refuses any .test.ts under src/ and names each one (vendored code is skipped). test/gate-stray-test.test.ts proves the refusal both ways: it fails with a stray file present and passes once the file is gone.

Following review, test/plugin-claude-oauth.test.ts and docs/MCP.md are back to main's version, so this pull is only the gate change: scripts/gate.ts, the moved test, and the new test. The stricter verb check, which reads the verbs from the /forge command instead of expecting a count of 12, is left out. It can be its own pull if it's wanted.

bun scripts/gate.ts and bun x tsc --noEmit pass, and so do these tests: test/gate-stray-test.test.ts, test/contain-label.test.ts, test/plugin-claude-oauth.test.ts and test/plugins.test.ts.

🤖 Generated with Claude Code

Approved

Approved. Single-purpose pull: the stray test moves into test/ (gated by presentTests), strayTestRefusal names each .test.ts under src/ (vendor excluded, sorted), it is wired into the gate main block, and the test proves it with a temp tree plus a self-check on this repo. The earlier unrelated plugin/MCP edits are gone. No web surface changed, so no phone or keyboard findings. Next two: (1) make the walk in strayTestRefusal also catch .test.tsx/.spec.ts so the next stray name does not slip past; (2) the stricter plugin verb check scout dropped can be its own pull if wanted.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs