Skip to content
Back to skills

Typesafe

ASecurity

Build features on TypeSafe's System One model (Jev): typed Choice/Score/Noul judgments with calibrated probabilities, consumed by code. Use when a decision needs semantic understanding but must stay cheap, fast, and inspectable — routing, ranking, extraction-by-selection, verification, screening. Triggers: '/typesafe', 'use jev', 'decision engine', 'classify this', 'confidence gate'. NOT for text generation, math, counting, or date arithmetic.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 25, 2026
ai-agentspythonrustgogitapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 25, 2026

npx -y skills add herakles-dev/typesafe-claude-kit --skill typesafe --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Typesafe?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Typesafe
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/herakles-dev-typesafe/badge)](https://www.skillsdirectory.com/skills/herakles-dev-typesafe)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: typesafe
version: "1.0.0"
category: decision-engine
model: inherit
color: cyan
triggers:
  - typesafe
  - system one
  - jev
  - decision engine
  - typed judgment
  - classify with probabilities
  - confidence gate
  - route on confidence
description: "Build features on TypeSafe's System One model (Jev): typed Choice/Score/Noul judgments with calibrated probabilities, consumed by code. Use when a decision needs semantic understanding but must stay cheap, fast, and inspectable — routing, ranking, extraction-by-selection, verification, screening. Triggers: '/typesafe', 'use jev', 'decision engine', 'classify this', 'confidence gate'. NOT for text generation, math, counting, or date arithmetic."
---

# TypeSafe (System One / Jev)

## What this is for

Jev returns **typed judgments with calibrated probabilities**. It does not generate text,
write code, or pick its own next action. Your code owns the workflow; Jev supplies semantic
judgment at specific points.

Use it when a decision needs common sense over unstructured input **and** you want the result
to be cheap, sub-second, and inspectable. At **$0.042 per million input tokens with free
output**, a judgment costs effectively nothing — which inverts the usual instinct to minimize
calls.

**Do not use it for:** generating text, arithmetic, counting, date comparison, or anything
code can compute exactly. Those are documented failure modes, not edge cases.

## Read the local corpus, not the web

Run `scripts/fetch-docs.sh` once to mirror the complete TypeSafe documentation into
`reference/` (gitignored). **Prefer those files over fetching docs.typesafe.ai per page** —
they are cleaned, offline, and already distilled.

| Need | Read |
|---|---|
| Everything, distilled | `knowledge/MASTERY.md` ← **start here** |
| Worked patterns by domain | `knowledge/cookbooks-{extraction,retrieval,reliability}.md` |
| A specific doc page | `reference/<path>.md` (109+ pages, fetched by `scripts/fetch-docs.sh`) |

Upstream changes without notice. If a version-dependent detail matters, re-fetch first.

## Use the shared client

Never hand-roll the HTTP call. `lib/typesafe_client.py` pins the model, validates against
documented limits before the request, retries 429/529 with backoff, and logs spend.

```python
import os, sys
KIT = os.environ.get("TYPESAFE_KIT", ".")
sys.path.insert(0, f"{KIT}/lib")
from typesafe_client import TypeSafeClient, choice, score, noul

client = TypeSafeClient()          # key from TYPESAFE_API_KEY env var (see .env.example)
result = client.ask(
    state={"ticket": "...", "policy": "..."},
    questions={
        "team":     choice("Which team handles `ticket`?", {"billing": "...", "eng": "...", "other": None}),
        "severity": score("How severe is `ticket`?", ["Cosmetic", "Degraded, workaround exists", "Blocking"]),
        "refund":   noul("Does `ticket` request a refund?"),
    },
    tag="my-surface",              # attributes spend in the usage log
)
result.choice("team"); result.confidence("team")
result.normalized_score("severity")   # 0-1, required before weighting
result.noul("refund")
```

The constructors validate at the call site: a Score with bare-number levels, 11 levels, or a
Choice with 256 options raises `ValueError` before any network call.

## The eight rules that matter

1. **Batch everything into one request.** Questions run in parallel and see the same state.
   Include speculative questions whose answers you may discard — the cookbook measurement is
   ~12x cheaper and ~10x faster than separate calls. A second round trip costs far more than
   a wasted question.

2. **Decompose ruthlessly.** This is the docs' own "most important concept". Replace
   `is_spam?` with six atomic Nouls (requests_credentials, sender_identity_mismatch,
   link_domain_mismatch, …) and weight them in code. Broad questions hide judgments you
   cannot inspect or tune.

3. **Pick the primitive by what your code does with the answer.**
   Choice → one of a set (relative: which option wins).
   Score → position on 2–10 ordered, *described* levels.
   Noul → P(condition holds) (absolute: is this true at all; no confidence field; 0.5 means
   "equally likely", not "medium").

4. **Score levels describe situations, never degrees.** "Moderately severe" gives the model
   nothing. Bare numbers measurably collapse accuracy (docs: 0.57 @ 0.35 confidence vs
   0.0 @ 1.0 with descriptions). Normalize by `len(levels) - 1` before combining scales.

5. **Select, don't generate.** Find candidates in code (regex, retrieval, enumeration), let
   Jev pick the right one. The model cannot choose a value you failed to offer — so
   over-generate candidates and let the judgment supply precision.

6. **Keep policy in code.** Weights, thresholds, and routing live in your code where you can
   read and change them. Raw judgments stay reusable: changing a weight needs no re-inference.

7. **Gate on confidence, scaled to risk.** One floor for genuine uncertainty, a higher bar for
   destructive actions. Every number is a hypothesis until measured on real labelled data —
   use `QuestionSet(gates_irreversible=True)`, which refuses to run until `validated_on` is set.

8. **Pin the model version.** `jev-latest` moves on release. Anything with a tuned threshold
   pins `jev-1.13.0`.

## Never send Jev these

Documented failure modes (`reference/model-jaggedness/jev-1.13.md`, run
`scripts/fetch-docs.sh` once; fallback: https://docs.typesafe.ai/model-jaggedness/jev-1.13.md):

arithmetic · counting (characters, occurrences, list items) · date/time comparison or ordering ·
numeric representations (hex, RGB, assembly) · interpolating a Score to recover a magnitude ·
text generation · multi-hop indirection · large state padded with irrelevant detail

And do not assume structural invariants: `P(x)` and `1 − P(not x)` are not comparable (measured
sum: 1.19), and a Noul threshold does not carry to a Choice.

**State is data, and Jev does not treat it as hostile by default.** Content designed to steer
the model can move the answer. Be explicit in criteria and test adversarial inputs before any
deployment that reads untrusted text.

## Structure your questions

`instructions` and every `criteria` value accept string, object, array, or null. Field names
are yours (`what`, `not_for`, `examples`, `question`, `focus`, `signals`). The highest-value
use is contrastive option definition:

```python
choice({"question": "Which topic?", "focus": "Classify what the user wants."},
       {"policy": {"what": "Whether an item can be returned",
                   "not_for": "Progress of a return already sent",
                   "examples": ["Can I return worn shoes?"]},
        "status": {"what": "Progress of a return already sent",
                   "not_for": "Whether an item can be returned",
                   "examples": ["When will my refund arrive?"]}})
```

Use the same field names across options. Examples only help when they resemble real inputs —
an unrelated example barely moves the answer, and higher confidence never proves correctness.

Point at nested state with backticked paths: `` `ticket.messages[0].text` ``.

## Defining a reusable decision

Bundle questions with their thresholds and provenance so they cannot drift apart:

```python
from questions import QuestionSet, register
MY_SET = register(QuestionSet(
    name="catalogue_action", version="1.0.0",
    description="Decide keep/deprecate/remove for a model catalogue entry.",
    questions={...},
    thresholds={"REMOVE_ABOVE": 0.9},      # named, never an inline literal
    gates_irreversible=True,
    validated_on=None,                      # -> .ask() refuses until filled in
))
```

## Checklist before shipping a TypeSafe integration

- [ ] Every question is one judgment, phrased literally
- [ ] All questions in one request; speculative ones included
- [ ] Score levels describe situations; scales normalized before weighting
- [ ] No math, counting, dates, or generation sent to the model
- [ ] `state` filtered to what the questions need
- [ ] Thresholds named, in code, and validated on real data before gating anything irreversible
- [ ] Model version pinned wherever a threshold exists
- [ ] Adversarial inputs tested if the state contains untrusted text

## Risk

**Low** for read-only classification and routing.
**Medium+** when a judgment gates a write, a deploy, a deletion, or an outbound message — those
require validated thresholds and a confidence floor that routes uncertainty to a human.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…