Skip to content

DecGuard v0.1: native System One backend, real Kev and Jev validation - #5

Merged
suffro merged 4 commits into
mainfrom
v0.1-real-backends
Sep 24, 2026
Merged

suffro merged 4 commits into
mainfrom
v0.1-real-backends

Conversation

@suffro

@suffro suffro commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

Closes the last DecGuard v0.1 release blocker: genuine end-to-end decisions through real Kev and real Jev (OpenRouter), validated in GitHub Actions on Ubuntu and macOS.

What changed

  • systemone backend (built in, src/decguard/backends/systemone.py). It speaks TypeSafe's System One wire format, which is shared by self-hosted Kev (POST /v1/systemone), TypeSafe's Jev, and OpenRouter's Decisions API (POST /api/alpha/decisions). It is a thin subclass of the http backend, so it reuses the httpx client, URL and credential checks, timeouts, retries, environment-only credentials, and the rule that error bodies are never recorded. It also retries HTTP 429 and 529. No new dependency and no vendor SDK.
    • choice: labels are sent as criteria option keys. The answer's probabilities are read by option, and choice must be the most probable option.
    • noul: no labels are sent. noul is the probability of the positive (first) contract label, and the negative label gets 1 − noul.
    • score: levels are sent as the ordered criteria list. probabilities are read by level index, and the legend must echo the levels sent.
    • Answers are validated strictly and never repaired. Normalization goes through the existing DecisionResult path (exact labels, canonical order, sum within probability_tolerance).
    • Provenance: model_version is the model that answered (e.g. typesafe/jev-1.13-20260917). Per-result metadata records request_id, upstream_provider and usage (input_tokens, output_tokens, cost). The report's backend lists served_models and upstream_providers.
  • Real-backend tests (tests/integration/test_real_backends.py, contracts in tests/integration/real/) with the markers real_kev and real_jev. They are skipped by default. Once selected with -m, a missing server, checkpoint or credential fails them. They assert successful decisions with valid probabilities, report generation, provenance, and that no secret appears in stdout, stderr, reports or exceptions. The last check includes a real rejected-key call (HTTP 401) with a canary key.
  • Real backends workflow (.github/workflows/real-backends.yml): manual (workflow_dispatch, or the real-backends label on a PR from this repository), Python 3.13 only. It runs four jobs: REAL KEV and REAL JEV on ubuntu-latest and macos-latest. OPENROUTER_API_KEY comes from repository secrets and is passed only to the Jev test step. The Kev weights are cached by pinned revision.
  • Unit tests for translation and normalization (tests/unit/test_systemone_backend.py, 36 tests).
  • Docs: docs/backends.md has the systemone reference and exact Kev and Jev/OpenRouter reproduction steps. Also updated: README, CHANGELOG, docs/ci.md, the .context/ state, and a decision record.

Real backends used

Kev Jev
Implementation upstream jaredpalmer/kev @ 09ff745d52a0f23954e3b0f5a608bf4c7c6aebb4, python -m kev.serve TypeSafe Jev through OpenRouter's Decisions API
Model jaredpalmer/kev-0.8b@9a45d25eb2ab761841196625383fa1dff0e56c1e (Kev-0.8B, the smallest current checkpoint; base Qwen/Qwen3.5-0.8B-Base) typesafe/jev-1.13, served as typesafe/jev-1.13-20260917
Runtime Ubuntu: CPU, torch fp32 · macOS: Apple Silicon, MLX bf16 https://openrouter.ai/api/alpha/decisions
Calls per run 3 per OS (choice, noul, score) 3 billed per OS (about $0.00001 each) + 1 rejected-key call (HTTP 401, not billed)

Jev rounds probabilities to two decimals, so the real contracts set evaluation.probability_tolerance: 0.02. The sum is still checked, never rescaled.

Evidence

Real-backend run 36067954968 on 95cc5bd:

REAL KEV REAL JEV
ubuntu-latest PASS (3/3, CPU torch fp32) PASS (4/4)
macos-latest PASS (3/3, MLX bf16) PASS (4/4)

Each Kev job logged serving jaredpalmer/kev-0.8b@9a45d25… on cpu via torch (float32) or … on mps via mlx (bfloat16). Each Jev decision has an OpenRouter gen-dec-… request id, upstream_provider: TypeSafe and served model typesafe/jev-1.13-20260917. Standard CI on the same commit: 36067948253. Lint, package, and Ubuntu/macOS × Python 3.11/3.12/3.13 are all green.

An earlier run (36067123735) passed all real tests, but its Kev jobs failed afterwards. A still-running uv run server held uv's cache lock, and setup-uv's post step timed out waiting for it. Fixed in 95cc5bd: the server now starts with the venv's Python and is stopped at the end of the job.

Local checks: ruff check, ruff format --check, mypy and pytest all pass (313 passed, 8 opt-in skips). uv build produces a wheel and sdist, and the clean-wheel smoke test (validate plus a real Kev decision) passes.

Not in this PR

No tag, PyPI release or GitHub release.

🤖 Generated with Claude Code

suffro and others added 2 commits September 25, 2026 00:22
Add the built-in `systemone` provider for TypeSafe System One decision
APIs: self-hosted Kev servers (`/v1/systemone`) and Jev through
OpenRouter's Decisions API. It subclasses the `http` backend to reuse its
client, timeouts, retries, environment-only credentials and the rule
that error bodies are never recorded, and adds 429/529 as retryable.

Choice labels are sent as criteria options, noul maps the probability of
yes to the positive label, and score maps level indices back to the
ordered levels. Answers are validated strictly and never repaired.

Add opt-in `real_kev` / `real_jev` integration tests that run genuine
inference, fail instead of skipping once selected, and check for secret
leakage, plus a manual workflow running them on Ubuntu and macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
workflow_dispatch only works for workflows on the default branch; a
`real-backends` label runs the same jobs on a pull request before merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@suffro suffro added the real-backends Run the real Kev/Jev backend workflow on this PR label Sep 24, 2026
suffro and others added 2 commits September 25, 2026 00:27
Document the `systemone` provider (wire translation, answer checks,
provenance, Jev's two-decimal rounding) and exact Kev and Jev/OpenRouter
reproduction steps with the required environment variables and secret.
Record the design decision and update the shared project context.

Share the label_map validation between `http` and `systemone`, and skip
the uv cache in the Kev job, whose torch stack is faster to download than
to restore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first run's Kev tests passed on both OSes, but the jobs failed:
`uv run` kept uv's cache lock while the server ran, so setup-uv's post
step timed out waiting for it. Start the server with the synced venv's
Python and stop it once the reports are shown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@suffro suffro added real-backends Run the real Kev/Jev backend workflow on this PR and removed real-backends Run the real Kev/Jev backend workflow on this PR labels Sep 24, 2026
@suffro
suffro marked this pull request as ready for review September 24, 2026 22:35
@suffro
suffro merged commit ba898c5 into main Sep 24, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

real-backends Run the real Kev/Jev backend workflow on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant