huncho

September 20, 2026 ยท View on GitHub

ci npm license

Decisions as code.

A hunch is a probability with a policy attached. huncho makes that a first-class object in TypeScript: ask typed questions of a decision model, apply thresholds that do not flap, nest decisions, journal every one, replay a policy change without inference, and calibrate against what actually happened.

Decision models are providers, not the product. Out of the box: TypeSafe Jev called directly, Jev through OpenRouter, Jev through Vercel AI Gateway, and a factory for anything else. Nothing above the model seam knows which vendor answered. Zero runtime dependencies.

npm i huncho
import { choice, huncho, noul } from "huncho";
import { jev } from "huncho/jev";

const route = huncho("support.route", { model: jev() })
  .ask({
    urgent: noul("Does this need a human within the hour?"),
    topic: choice("What is it about?", ["billing", "bug", "other"]),
  })
  .when((a) => a.urgent.p, { enter: 0.8, exit: 0.6 }, "page")
  .when((a) => a.topic.is("billing", 0.7), "billing")
  .else("triage");

const decision = await route.decide("Checkout is down. Every customer gets a 500 at payment.", { key: "T-1041" });
decision.outcome;   // "page" | "billing" | "triage"
decision.via;       // "enter" | "hold" | "else": how the outcome was reached
decision.previous;  // what this key decided last time, if anything

jev() reads TYPESAFE_API_KEY the first time it is called. { enter: 0.8, exit: 0.6 } is hysteresis: the ticket enters page at 0.8 and stays there until urgency drops below 0.6, per key. Answer types follow from the questions, so a.topic.p("refund") is a compile error.

Docs

The documentation is the site at edgardcham.github.io/huncho. It is built from this repo, so the pages under docs/ and the scripts under examples/ are the source, and the API reference is generated from the type declarations.

CONTRIBUTING.md is the working agreement and the module map.

Packages

EcosystemPackageStatus
npmhuncho0.5.0; the public API has been frozen since 0.1.0, CHANGELOG.md records every change to it and stability says what a version number means
PyPIhunchonext, ported from the fixtures now that the TypeScript API is frozen

One set of fixtures for wire dialects and policy semantics; each port passes the same files, and journals are interchangeable.

License

MIT