Skip to main content

max / makenotwork

Scope the server's mutation runs by blast radius Unscoped this crate generates 9,766 mutants and each re-runs the suite, so a pass is about six days of machine. It has consequently never completed once, which meant no mutation data at all for the largest thing we ship. 2,610 now. Ordered money, then user data, then the security boundary. A survivor is a line whose behaviour no test observes, so the question is where we can be wrong without finding out, and that matters most where being wrong costs a creator money or their files. Only files that already have tests. Mutating an untested file reports every mutant as a survivor, which buries the real findings and answers a question grep answers for free. 50 files in the money and user-data groups have no test at all, among them db/transactions/purchases.rs at 1,375 lines, db/users.rs at 1,269 and routes/stripe/webhook/checkout.rs at 1,024. db/subscriptions.rs looks tested and is not: its only `#[cfg(test)]` is a test-only constructor. Those are a coverage gap to close rather than a mutation result to compute.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-04 21:41 UTC
Signed with PGP, not checked
Commit: 1e710002b25e4f9d1d44f9b71b0838229ad8b072
Parent: 591a707
1 file changed, +96 insertions, -0 deletions
@@ -1,0 +1,96 @@
1 + # Mutation scope for the MNW server.
2 + #
3 + # Not a tuning knob. Unscoped, this crate generates 9,766 mutants and each one
4 + # re-runs the test suite, so a single pass is roughly six days of machine. It
5 + # has therefore never completed, which meant no mutation data at all for the
6 + # largest thing we ship. Scoping is what makes the check exist.
7 + #
8 + # Two rules decide what is in here, and both are deliberate.
9 + #
10 + # 1. Ordered by blast radius: money first, then user data, then the security
11 + # boundary. A survivor is a line whose behaviour no test observes, so this
12 + # check answers "where can we be wrong and not find out", and the answer
13 + # matters most where being wrong costs a creator money or their files.
14 + #
15 + # 2. Only files that already have tests. Mutating a file with no test reports
16 + # every mutant as a survivor, which is noise at a volume that buries the real
17 + # findings, and it answers a question `grep` answers for free. 50 files in
18 + # the money and user-data groups have no test at all, including
19 + # db/transactions/purchases.rs (1,375 lines), db/users.rs (1,269) and
20 + # routes/stripe/webhook/checkout.rs (1,024). That is a coverage gap to close,
21 + # not a mutation result to compute; the list is in wiki `testing-posture`.
22 + #
23 + # Add a file here when it gains its first test, rather than when it is written.
24 + # Method and the untested list: wiki `testing-posture`.
25 +
26 + examine_globs = [
27 +
28 + # --- Money. A survivor here is a way the ledger can be wrong without any
29 + # test noticing.
30 + # 14 files, 7,370 lines, 230 tests.
31 + "src/db/creator_tiers/mod.rs",
32 + "src/db/creator_tiers/storage_quota.rs",
33 + "src/db/creator_tiers/subscriptions.rs",
34 + "src/db/promo_codes.rs",
35 + "src/helpers/billing.rs",
36 + "src/payments/checkout_metadata.rs",
37 + "src/payments/connect.rs",
38 + "src/payments/synckit_app_pricing.rs",
39 + "src/payments/webhooks.rs",
40 + "src/pricing.rs",
41 + "src/pricing_comparison.rs",
42 + "src/routes/stripe/webhook/checkout_helpers.rs",
43 + "src/synckit_billing.rs",
44 + "src/tier_prices.rs",
45 +
46 + # --- User data. A survivor here is a way a creator's files, sync state or
47 + # account can be corrupted or lost silently.
48 + # 9 files, 6,780 lines, 147 tests.
49 + "src/import/csv_converter.rs",
50 + "src/import/mod.rs",
51 + "src/import/pipeline.rs",
52 + "src/routes/storage/media.rs",
53 + "src/routes/storage/mod.rs",
54 + "src/routes/synckit/billing.rs",
55 + "src/routes/synckit/keys.rs",
56 + "src/routes/synckit/mod.rs",
57 + "src/storage.rs",
58 +
59 + # --- Auth, access control, input validation and scanning. Every file in
60 + # this group already has tests; mutation asks if they are strong enough.
61 + # 34 files, 18,514 lines, 593 tests.
62 + "src/access_gate.rs",
63 + "src/auth.rs",
64 + "src/crypto.rs",
65 + "src/csrf.rs",
66 + "src/custom_pages/css_sanitizer.rs",
67 + "src/custom_pages/html_sanitizer.rs",
68 + "src/custom_pages/mod.rs",
69 + "src/custom_pages/url_filter.rs",
70 + "src/db/scan_jobs.rs",
71 + "src/extractors.rs",
72 + "src/git_ssh.rs",
73 + "src/oauth_scope.rs",
74 + "src/rate_limit.rs",
75 + "src/scanning/archive.rs",
76 + "src/scanning/clamav.rs",
77 + "src/scanning/content_type.rs",
78 + "src/scanning/hash_lookup.rs",
79 + "src/scanning/metadefender.rs",
80 + "src/scanning/mod.rs",
81 + "src/scanning/signing_linux.rs",
82 + "src/scanning/signing_macos.rs",
83 + "src/scanning/signing_windows.rs",
84 + "src/scanning/spool.rs",
85 + "src/scanning/structural.rs",
86 + "src/scanning/urlhaus.rs",
87 + "src/scanning/worker.rs",
88 + "src/scanning/yara.rs",
89 + "src/security_signals.rs",
90 + "src/synckit_auth.rs",
91 + "src/validation/items.rs",
92 + "src/validation/mod.rs",
93 + "src/validation/payments.rs",
94 + "src/validation/projects.rs",
95 + "src/validation/users.rs",
96 + ]