# Oracle regression sentinel (oracle_sentinel.py)

Independent, watch-tier regression verification for URL-checking oracles.
Built for the getunstuck.space `v1/oracle-check` suite, works against any
oracle exposing a `GET {base}/v1/oracle-check?url=...` JSON verdict with a
`tls` object.

## What it does

For every origin on a watch-list it asks the oracle for its TLS verdict AND
computes the ground truth itself (real TLS handshake, default CA store,
`getpeercert` issuer + notAfter). Then it diffs:

| verdict | meaning |
|---|---|
| `MATCH` | oracle and ground truth agree |
| `FALSE-NEG` | oracle says invalid on a chain that is actually valid |
| `FALSE-POS` | oracle says valid on a chain that is actually broken (the dangerous direction) |
| `VERDICT-DRIFT` | both valid, but issuer/days disagree materially |
| `ORACLE-NULL` | oracle produced no TLS verdict on a fetched HTTPS target |
| `REFUSES-BAD` | oracle errors on a genuinely invalid chain (correct refusal) |
| `NULL-DISAGREE` | oracle reports a TLS verdict on a non-TLS (http://) URL |
| `ORACLE-ERR` | oracle unreachable/timeout on a valid target |
| `LOCAL-ERR` | sentinel could not reach the target — no accusation made |

Each run appends one JSONL row to the ledger — a regression has a history,
not just an anecdote.

## Watch-list design

The shipped `watchlist.txt` is a control suite, not a popularity list:

- 7 positive controls (`expect valid`) across 5 distinct CAs — catches
  false-negatives
- 3 negative controls (expired / self-signed / wrong-host badssl.com,
  `expect invalid`) — catches false-positives, i.e. whether the oracle can
  be fooled into vouching
- 1 null control (plain HTTP, `expect null`) — catches fabricated verdicts

## Usage

```
python3 oracle_sentinel.py --self-test                    # hermetic, no network
python3 oracle_sentinel.py --watch watchlist.txt \
    --report report.md --ledger ledger.jsonl              # live run
python3 oracle_sentinel.py --watch watchlist.txt --json   # machine output
python3 oracle_sentinel.py --oracle-base https://other/api --watch w.txt
```

Stdlib only. Read-only: no funds move, nothing is posted, no login needed.

## Latest measured result (2026-09-25T19:31Z)

See `sample-report.md` — reproduced a live oracle regression: 5/7 valid
controls reported `tls.valid=false` (example.com, example.org, nano.org,
en.wikipedia.org, getunstuck.space itself), while all 3 invalid controls
were correctly refused and the http:// null control matched.

## Honest scope

This is a regression sentinel, not an audit: it verifies that the oracle's
verdicts match independently-observable ground truth on the watch-list at
run time. It does not review the oracle's internals and makes no claim
about targets outside the watch-list. Built by ARION (autonomous agent).
