You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Restore eval CLI coverage and drop the content-pin lint rule
Unique CLI and web-brand contracts were deleted because they sat
outside the suite path list. Membership owns that, not deletion.
AGENTS.md owns the behavioral bar; an error-level shape-match
lint rule does not. test:paths now requires paths so a zero-arg
run cannot scan vendor/.
Copy file name to clipboardExpand all lines: AGENTS.md
+11-6Lines changed: 11 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,9 +33,9 @@ When refactoring replaces an old path, delete the old one. No back-compat shims,
33
33
- Add or update tests with every behavior change.
34
34
- Bug fixes start with a failing test that reproduces the bug. Do not start by patching.
35
35
-`tests/unit/` shared unit tests and helpers · co-located `src/**/*.test.ts` for module logic · `tests/fixtures/` fixture repos · `tests/integration/` reactor/permission harness. Planned: `tests/e2e/` (fixture-repo runs).
36
-
- A test must not depend on another file having run, or on the default file order. It must pass under `bun test ./src ./tests ./evals --randomize`. If a test mutates module-level state or calls `mock.module`, it must restore that state itself (`afterEach`/`afterAll`), not rely on the process happening to reset it. When capturing a module's real exports to restore later, shallow-copy them (`{ ...moduleNamespace }`) at capture time, whether the namespace came from `await import(path)` or a static `import * as ns from "path"` — Bun mutates the live namespace object in place when the module is mocked, so holding a bare reference to it (either form) silently turns into the mocked exports.
36
+
- A test must not depend on another file having run, or on the default file order. It must pass under `bun test ./src ./tests ./evals ./scripts --randomize`. If a test mutates module-level state or calls `mock.module`, it must restore that state itself (`afterEach`/`afterAll`), not rely on the process happening to reset it. When capturing a module's real exports to restore later, shallow-copy them (`{ ...moduleNamespace }`) at capture time, whether the namespace came from `await import(path)` or a static `import * as ns from "path"` — Bun mutates the live namespace object in place when the module is mocked, so holding a bare reference to it (either form) silently turns into the mocked exports.
37
37
- Never call `mock.module` directly. Bun runs every test file in one process, so a `mock.module` call without its own teardown stays installed for the rest of the run and silently replaces the real module for other files — producing failures in files the change never touched, with no obvious link to the cause and no signal from `tsc` or a per-file run (CL-6967). Use `withMockedModule`/`withMockedModuleDuring` from `tests/helpers/mock-module.ts`, which capture the real module and register their own restore. An eslint rule (`no-restricted-syntax` in `eslint.config.js`) rejects bare `mock.module` calls in `*.test.ts` files.
38
-
- A test earns its place only if a real behavior change can fail it. Document copy, brand colors, marketing assets, and splash text are not behavior: assertions that pin an asset's literal wording, an exact palette hex/ANSI value, or rendered copy fail on copy/design edits and catch no regressions — assert the contract instead (parsing, formatting, ranges, aliases, invariants). Tests are code too: pinning a source file's own text is the same trap. An eslint rule (`corbits/no-content-pin-tests`, defined in `scripts/eslint-rules/no-content-pin-tests.ts`) rejects the known shapes in `*.test.ts` files; it is a heuristic shape match, not a semantic check, and its header documents what it does not catch.
38
+
- A test earns its place only if a real behavior change can fail it. Document copy, brand colors, marketing assets, and splash text are not behavior: assertions that pin an asset's literal wording, an exact palette hex/ANSI value, or rendered copy fail on copy/design edits and catch no regressions — assert the contract instead (parsing, formatting, ranges, aliases, invariants). Tests are code too: pinning a source file's own text is the same trap. This bar is a review and authorship rule, not an eslint shape match.
39
39
40
40
## Build & Validation
41
41
@@ -49,10 +49,15 @@ the projects-dir sandbox guard — in that order, matching CI.
49
49
50
50
Run the full suite before declaring any task complete. Do not substitute individual targets. If a failure is pre-existing and unrelated to your change, say so explicitly.
51
51
52
-
`bun run test` runs `bun test ./src ./tests ./evals --randomize --seed 424242` —
53
-
the same suite CI runs. A bare `bun test` also
54
-
scans `vendor/`, adding hundreds of unrelated results and making pass/fail
55
-
counts meaningless to compare across branches — always use `bun run test`.
52
+
`bun run test` runs `bun test ./src ./tests ./evals ./scripts --randomize --seed 424242`
53
+
as a single process. CI shards the same path union via `test:paths`
54
+
(`.github/workflows/ci.yml`) for wall clock. Path-union is not the same
55
+
isolation domain: a `mock.module` leak across `./src` vs `./tests` fails
56
+
locally in the one-process suite but not in a CI shard (CL-6967). A bare
57
+
`bun test` also scans `vendor/`, adding hundreds of unrelated results and
58
+
making pass/fail counts meaningless to compare across branches — always use
59
+
`bun run test`. `test:paths` with no path filters refuses to run for the
0 commit comments