Metadata-Version: 2.4
Name: lookingeye
Version: 0.2.1
Summary: Substrate-specific operational verdicts for Hugging Face Spaces — detect ZeroGPU silent-fails, worker errors, and quota burn that HF won't tell you about.
Author: LookingEye
License: Apache-2.0
Project-URL: Homepage, https://lookingeye.draftlabs.org
Keywords: huggingface,verdict,zerogpu,sigstore,lookingeye
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-cov>=5; extra == "dev"

# lookingeye

Substrate-specific operational verdicts for Hugging Face Spaces. Goal: detect runtime failures that HF won't tell you about (ZeroGPU silent worker errors, async deadlocks, quota burn). Shipped in phases — see "What this version detects" below for exactly what's live today.

## Install

```
pipx install lookingeye
```

Or with pip:

```
pip install lookingeye
```

## Quickstart

```
lookingeye --version
lookingeye verify owner/your-hf-model
```

Each run writes a SHAPE-valid `lookingeye-report.json` to `./.lookingeye/<model_id>-<timestamp>.json` and prints a one-screen summary.

Example:

```
$ lookingeye verify gpt2
LookingEye verdict — model: gpt2
  decision:       generated
  hub:            reachable
  model:          confirmed public
  probe:          367 ms
  warning_codes:  (none)
  report written: .lookingeye/gpt2-2026-05-26T18-32-59.171Z.json
```

## What this version detects (v0.2.1, Phase A)

Live today:

- ✅ **`hub_unreachable`** — fires on network error, DNS failure, or 5xx from HF Hub. Decision: `refused`.
- ✅ **`hf_hub_reachable` + `model_found`** populated in `runtime_evidence` when probe succeeds for a public model.

Honest limit (documented in `lookingeye/probe.py`):

- ⚠️ HF returns **HTTP 401 for both nonexistent and gated models, indistinguishably** (verified against the live API 2026-05-26). They do this deliberately to prevent model-name enumeration. Without an HF token, the CLI cannot tell a typo from a gated model — it reports `model_found: null` honestly rather than guessing.

Coming next:

- 🚧 **v0.3 — Phase A.5:** accept `HF_TOKEN` env var to disambiguate 401 → nonexistent vs gated, and unlock `model_not_found` warning.
- 🚧 **v0.4 — Phase B:** Space probe → `zerogpu_worker_ok`, `invocation_succeeded`, `silent_hang`.
- 🚧 **v0.5 — Phase C:** `quota_remaining_pct`, `quota_burn`.

## Telemetry (opt-in)

`lookingeye` never sends telemetry unless you opt in. To enable:

```
lookingeye --opt-in
```

You'll be prompted for an email. We SHA-256 the email locally and only send the hash plus the CLI version + invocation event. No model contents, no source code, no raw PII ever leaves your machine.

To revoke:

```
lookingeye --opt-out
```

State is stored at `~/.config/lookingeye/state.json` (override with `LOOKINGEYE_STATE_DIR`).

## Privacy

Telemetry is governed by `.lookingeye/PRIVACY.md` in this repository. The SaaS endpoint that receives pings is `https://lookingeye.draftlabs.org/api/cli/ping` and is documented in `experiment/EVENTS.yaml`.
