ci: enforce the checks the contributor rules already required
Four gates that were documented but unenforced, plus the flaky test that made a full-suite run untrustworthy. Rust lint/format: CLAUDE.md has required `cargo fmt` and `cargo clippy` before every commit for as long as the rule existed, yet neither ran anywhere in CI — the requirement rested on memory alone. Both now run in build-and-test.yml and build-release.yml. rustfmt and clippy are already baked into the builder image, so nothing is installed at job time. `cargo fmt --all -- --check` is strict immediately (the tree is clean). Clippy is advisory for now: ~51 pre-existing warnings mean `-D warnings` would fail on unrelated work, so the step carries a TODO to flip the flag once the backlog clears. A compile error still fails it, so it is not a no-op. Traceability threshold: MIN_THRESHOLD sat at 50 while real coverage was 86%, so nearly half the matrix could rot before the gate objected. Ratcheted to 82 with the policy written down — it only ever goes up, and is never lowered to make a red build pass. The same figure lives in MIN_COVERAGE_PERCENT so `traces:coverage` gates locally on the same bar, and a test fails if the two drift. Dangling IDs: a TRACES comment could name any well-formed ID and the extractor accepted it silently, so typos and renames that missed a call site passed unnoticed. `bun run traces:validate` cross-checks every traced ID against the table rows in requirements.md and fails with the referencing files listed. It spans UT/IT as well, which the coverage orphan list ignores by design. This currently reports DR-189 and UT-188, which are being defined separately. Flaky offlineCatalog test: the first dynamic import of the service paid ~1s to transform its dependency graph, charged to a test body against vitest's 5s default. Alone it passed; under suite-wide contention it timed out. The import is now warmed at collection time, so no test is timing the compiler — the timeout is deliberately unchanged. The store shim also drops subscribers from module instances discarded by resetModules, which previously leaked across tests.
This commit is contained in:
@@ -23,6 +23,13 @@ const h = vi.hoisted(() => {
|
||||
fn(value);
|
||||
return () => subs.delete(fn);
|
||||
},
|
||||
// Drop subscribers left behind by module instances discarded via
|
||||
// `vi.resetModules()`. Without this, every previously-imported copy of the
|
||||
// service still reacts to `set()` and pushes its own visibility value.
|
||||
reset(v: T) {
|
||||
subs.clear();
|
||||
value = v;
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -31,6 +38,21 @@ const h = vi.hoisted(() => {
|
||||
};
|
||||
});
|
||||
|
||||
// Prime the module graph once, at collection time, instead of inside a test.
|
||||
//
|
||||
// Every test re-imports the service after `vi.resetModules()` so it gets a fresh
|
||||
// set of module-level subscriptions. The *first* of those imports also pays to
|
||||
// transform the service and its dependency graph — around a second of real
|
||||
// wall-clock work with a cold Vite cache. Charged to a test body that cost sat
|
||||
// close enough to vitest's 5s default that suite-wide contention (many workers
|
||||
// transforming at once) tipped this file into a timeout, while running the file
|
||||
// alone always passed. Warming here moves the compile out of the timed region;
|
||||
// the per-test re-imports that follow are cached and cost ~30ms.
|
||||
//
|
||||
// The timeout is deliberately left at the default: the point is to stop timing
|
||||
// the compiler, not to give it a bigger budget.
|
||||
await import("./offlineCatalog");
|
||||
|
||||
vi.mock("$lib/stores/connectivity", () => ({
|
||||
isConnected: { subscribe: h.isConnectedStore.subscribe },
|
||||
}));
|
||||
@@ -50,8 +72,8 @@ vi.mock("$lib/stores/auth", () => ({
|
||||
|
||||
describe("pushCatalogVisibility resolves reachable || showCatalog (UT-068)", () => {
|
||||
beforeEach(() => {
|
||||
h.isConnectedStore.reset(true);
|
||||
h.setShowServerCatalog.mockClear();
|
||||
h.isConnectedStore.set(true);
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user