Skip to content

Instantly share code, notes, and snippets.

@mikesol
Created February 22, 2026 19:15
Show Gist options
  • Select an option

  • Save mikesol/c6df8b2670023508d81b0a45afe4d396 to your computer and use it in GitHub Desktop.

Select an option

Save mikesol/c6df8b2670023508d81b0a45afe4d396 to your computer and use it in GitHub Desktop.
Spike: ExtractKinds + StrictPlugin for ctor-kind consistency enforcement
/**
* Spike: enforce ctor-kind consistency at the Plugin type level.
*
* ExtractKinds<T> recursively walks a type tree and collects all CExpr
* kind strings — through functions, builder chains, nested objects,
* closure returns, and callback parameter types.
*
* StrictPlugin uses this to reject plugins where ctors produce CExpr
* nodes with kinds not declared in the `kinds` map.
*
* Tested against all patterns in the codebase:
* - Simple arity-N (num/add)
* - Builder chains (error/try...catch)
* - Closure-returning (st/let → {get, set})
* - Nested objects (redis: {get, set})
*
* Known gap: side-effecting ctors (st/let creates st/let via push to
* effects array, not via return type) — can't be seen by type system.
*/
import type { CExpr } from "@mvfm/core";
import type { KindSpec, Interpreter, TraitDef } from "@mvfm/core";
// ─── ExtractKinds ───────────────────────────────────────────────────
type ExtractKinds<T> =
T extends CExpr<any, infer K extends string, any>
? K
: T extends (...args: any[]) => infer R
? ExtractKinds<R>
: T extends Record<string, unknown>
? { [P in keyof T]: ExtractKinds<T[P]> }[keyof T]
: never;
// ─── StrictPlugin ───────────────────────────────────────────────────
interface StrictPlugin<
Name extends string = string,
Ctors = any,
Kinds extends Record<string, KindSpec<any, any>> = any,
Traits extends Record<string, TraitDef<any, any>> = any,
Lifts extends Record<string, string> = any,
> {
readonly name: Name;
readonly ctors: [ExtractKinds<Ctors>] extends [keyof Kinds] ? Ctors : never;
readonly kinds: Kinds;
readonly traits: Traits;
readonly lifts: Lifts;
readonly defaultInterpreter?: () => Interpreter;
readonly shapes?: Record<string, unknown>;
}
// ─── Example: passes ────────────────────────────────────────────────
// const good = {
// name: "test",
// ctors: {
// add: <A, B>(a: A, b: B): CExpr<unknown, "test/add", [A, B]> =>
// makeCExpr("test/add", [a, b]),
// },
// kinds: {
// "test/add": { inputs: [0, 0], output: 0 } as KindSpec<[number, number], number>,
// },
// traits: {},
// lifts: {},
// } satisfies StrictPlugin;
// ─── Example: fails (unregistered kind) ─────────────────────────────
// const bad = {
// name: "test",
// ctors: {
// add: <A, B>(a: A, b: B): CExpr<unknown, "test/add", [A, B]> =>
// makeCExpr("test/add", [a, b]),
// sub: <A, B>(a: A, b: B): CExpr<unknown, "test/sub", [A, B]> =>
// makeCExpr("test/sub", [a, b]),
// },
// kinds: {
// "test/add": { inputs: [0, 0], output: 0 } as KindSpec<[number, number], number>,
// // "test/sub" NOT registered — `satisfies StrictPlugin` fails!
// },
// traits: {},
// lifts: {},
// } satisfies StrictPlugin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment