| name | convex-verify |
| description | Prove a Convex feature works — seed, drive as multiple mocked users via convex-test, assert behavior including the negative authz cases (wrong user refused, data-scope enforced). |
Prove a feature works — seed, drive, assert
A green typecheck proves the code parses; it does not prove a non-owner is actually denied, that a query returns the right rows, or that a mutation has the effect it claims. This capability closes that gap with the loop the whole field is missing: seed → drive → assert, run in-process with convex-test so it needs no deployment. Its highest-value assertions are the NEGATIVE ones — the caller who should be refused — because those are exactly the authz defects the 30-app corpus shows are the #1 real bug and the ones a happy-path demo never catches.
Workflow
- IDENTIFY the feature to prove: the specific exported query/mutation/action (or a small set) the user just built/changed, and its intended behavior — who should be allowed, what data should come back, what a mutation should change. If the intent is unstated, ask one focused question rather than guessing the contract.
- SET UP
convex-test: ensure convex-test + vitest are dev deps AND a vitest.config.ts sets test.environment: "edge-runtime" with server.deps.inline: ["convex-test"] — WITHOUT that config, convexTest(schema) fails at runtime with import.meta.glob is not a function (verified). Also install @edge-runtime/vm. Then convexTest(schema) gives a t handle. Reuse the project's existing test setup if present (compose with the test capability, don't fork it).
- SEED realistic data through the app's OWN functions where possible (so the seed exercises the same validators/mutations a real user would), falling back to
t.run(async (ctx) => ctx.db.insert(...)) for fixtures the public API can't create. Seed at least: the caller's own rows AND a second user's rows, so cross-user access is testable.