vetcheck 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vetcheck/__init__.py +225 -0
- vetcheck/drift.py +133 -0
- vetcheck/exam.py +161 -0
- vetcheck/quarantine.py +188 -0
- vetcheck-0.1.0.dist-info/METADATA +383 -0
- vetcheck-0.1.0.dist-info/RECORD +9 -0
- vetcheck-0.1.0.dist-info/WHEEL +5 -0
- vetcheck-0.1.0.dist-info/licenses/LICENSE +21 -0
- vetcheck-0.1.0.dist-info/top_level.txt +1 -0
vetcheck/__init__.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Vetcheck: Model health monitoring as veterinary care.
|
|
3
|
+
|
|
4
|
+
In the working dog paradigm, dogs need regular checkups.
|
|
5
|
+
This does the same for models.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import time
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from enum import Enum
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from vetcheck.exam import ExamResult, run_physical_exam
|
|
17
|
+
from vetcheck.drift import DriftReport, check_weight_drift
|
|
18
|
+
from vetcheck.quarantine import QuarantineStatus, quarantine_model, release_model, get_quarantine_status
|
|
19
|
+
|
|
20
|
+
__version__ = "0.1.0"
|
|
21
|
+
__all__ = [
|
|
22
|
+
"VetCheck",
|
|
23
|
+
"ExamResult",
|
|
24
|
+
"DriftReport",
|
|
25
|
+
"QuarantineStatus",
|
|
26
|
+
"HealthStatus",
|
|
27
|
+
"HealthCertificate",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class HealthStatus(str, Enum):
|
|
32
|
+
"""Overall health status of a model — like a vet's diagnosis."""
|
|
33
|
+
HEALTHY = "healthy"
|
|
34
|
+
UNDER_OBSERVATION = "under_observation"
|
|
35
|
+
QUARANTINED = "quarantined"
|
|
36
|
+
CRITICAL = "critical"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class HealthCertificate:
|
|
41
|
+
"""A clean bill of health — like a health certificate from the vet."""
|
|
42
|
+
model_id: str
|
|
43
|
+
status: HealthStatus
|
|
44
|
+
issued_at: float
|
|
45
|
+
expires_at: float
|
|
46
|
+
last_exam_passed: bool
|
|
47
|
+
weight_stable: bool
|
|
48
|
+
quarantine_active: bool
|
|
49
|
+
notes: str = ""
|
|
50
|
+
|
|
51
|
+
def is_valid(self, now: float | None = None) -> bool:
|
|
52
|
+
"""Check if this certificate is still within its expiry."""
|
|
53
|
+
now = now or time.time()
|
|
54
|
+
return now < self.expires_at
|
|
55
|
+
|
|
56
|
+
def to_dict(self) -> dict[str, Any]:
|
|
57
|
+
return {
|
|
58
|
+
"model_id": self.model_id,
|
|
59
|
+
"status": self.status.value,
|
|
60
|
+
"issued_at": self.issued_at,
|
|
61
|
+
"expires_at": self.expires_at,
|
|
62
|
+
"last_exam_passed": self.last_exam_passed,
|
|
63
|
+
"weight_stable": self.weight_stable,
|
|
64
|
+
"quarantine_active": self.quarantine_active,
|
|
65
|
+
"notes": self.notes,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def __repr__(self) -> str:
|
|
69
|
+
return (
|
|
70
|
+
f"HealthCertificate(model={self.model_id!r}, status={self.status.value}, "
|
|
71
|
+
f"valid_until={time.strftime('%Y-%m-%d %H:%M', time.gmtime(self.expires_at))} UTC)"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class VetCheck:
|
|
76
|
+
"""
|
|
77
|
+
The veterinarian for your models.
|
|
78
|
+
|
|
79
|
+
Usage:
|
|
80
|
+
vet = VetCheck(model_id="llama-3-70b")
|
|
81
|
+
report = vet.physical_exam()
|
|
82
|
+
drift = vet.weight_check()
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def __init__(
|
|
86
|
+
self,
|
|
87
|
+
model_id: str,
|
|
88
|
+
baseline: list[dict[str, Any]] | None = None,
|
|
89
|
+
registry: dict[str, Any] | None = None,
|
|
90
|
+
exam_suite: list[dict[str, Any]] | None = None,
|
|
91
|
+
certificate_ttl: float = 86400.0, # 24 hours
|
|
92
|
+
):
|
|
93
|
+
self.model_id = model_id
|
|
94
|
+
self._baseline = baseline or []
|
|
95
|
+
self._registry = registry or {}
|
|
96
|
+
self._exam_suite = exam_suite or _default_exam_suite()
|
|
97
|
+
self._certificate_ttl = certificate_ttl
|
|
98
|
+
self._last_exam: ExamResult | None = None
|
|
99
|
+
self._last_drift: DriftReport | None = None
|
|
100
|
+
|
|
101
|
+
def physical_exam(self, suite: list[dict[str, Any]] | None = None) -> ExamResult:
|
|
102
|
+
"""
|
|
103
|
+
Run a full physical exam — the regression test suite.
|
|
104
|
+
|
|
105
|
+
Each test is a vital sign check. Returns a full ExamResult
|
|
106
|
+
with pass/fail per test and an overall health assessment.
|
|
107
|
+
"""
|
|
108
|
+
suite = suite or self._exam_suite
|
|
109
|
+
result = run_physical_exam(self.model_id, suite)
|
|
110
|
+
self._last_exam = result
|
|
111
|
+
|
|
112
|
+
# Auto-quarantine on critical failures
|
|
113
|
+
if result.critical_failures > 0:
|
|
114
|
+
self.quarantine(reason=f"Critical failures in physical exam: {result.critical_failures}")
|
|
115
|
+
|
|
116
|
+
return result
|
|
117
|
+
|
|
118
|
+
def weight_check(
|
|
119
|
+
self,
|
|
120
|
+
recent_outputs: list[dict[str, Any]] | None = None,
|
|
121
|
+
window: int = 100,
|
|
122
|
+
threshold: float = 0.05,
|
|
123
|
+
) -> DriftReport:
|
|
124
|
+
"""
|
|
125
|
+
Check for weight drift — output distribution shift over time.
|
|
126
|
+
|
|
127
|
+
Like weighing a dog at every visit, this compares recent
|
|
128
|
+
outputs against the baseline to detect statistically
|
|
129
|
+
significant drift.
|
|
130
|
+
"""
|
|
131
|
+
recent = recent_outputs or self._baseline[-window:]
|
|
132
|
+
baseline = self._baseline[:window] if len(self._baseline) > window else self._baseline
|
|
133
|
+
report = check_weight_drift(self.model_id, baseline, recent, threshold=threshold)
|
|
134
|
+
self._last_drift = report
|
|
135
|
+
return report
|
|
136
|
+
|
|
137
|
+
def quarantine(self, reason: str) -> QuarantineStatus:
|
|
138
|
+
"""
|
|
139
|
+
Quarantine a sick model — isolate it from production traffic.
|
|
140
|
+
|
|
141
|
+
The model stays in quarantine until a clean physical exam
|
|
142
|
+
passes and release() is explicitly called.
|
|
143
|
+
"""
|
|
144
|
+
return quarantine_model(self.model_id, reason, registry=self._registry)
|
|
145
|
+
|
|
146
|
+
def release(self) -> QuarantineStatus:
|
|
147
|
+
"""
|
|
148
|
+
Release a model from quarantine back to active duty.
|
|
149
|
+
|
|
150
|
+
Requires a recent, passing physical exam.
|
|
151
|
+
"""
|
|
152
|
+
if self._last_exam and not self._last_exam.passed:
|
|
153
|
+
raise ValueError(
|
|
154
|
+
f"Cannot release {self.model_id}: last physical exam did not pass. "
|
|
155
|
+
"Run physical_exam() and ensure it passes before releasing."
|
|
156
|
+
)
|
|
157
|
+
return release_model(self.model_id, registry=self._registry)
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def status(self) -> HealthStatus:
|
|
161
|
+
"""Current health status of the model."""
|
|
162
|
+
q = get_quarantine_status(self.model_id, registry=self._registry)
|
|
163
|
+
if q.is_quarantined:
|
|
164
|
+
return HealthStatus.QUARANTINED
|
|
165
|
+
|
|
166
|
+
if self._last_exam and not self._last_exam.passed:
|
|
167
|
+
return HealthStatus.CRITICAL
|
|
168
|
+
|
|
169
|
+
if self._last_drift and self._last_drift.is_significant:
|
|
170
|
+
return HealthStatus.UNDER_OBSERVATION
|
|
171
|
+
|
|
172
|
+
return HealthStatus.HEALTHY
|
|
173
|
+
|
|
174
|
+
def health_certificate(self, force: bool = False) -> HealthCertificate:
|
|
175
|
+
"""
|
|
176
|
+
Issue a health certificate — a clean bill of health.
|
|
177
|
+
|
|
178
|
+
Verifies:
|
|
179
|
+
- Last physical exam passed
|
|
180
|
+
- No active quarantine
|
|
181
|
+
- Weight (drift) is stable
|
|
182
|
+
|
|
183
|
+
Raises ValueError if the model is not healthy unless force=True.
|
|
184
|
+
"""
|
|
185
|
+
last_passed = self._last_exam is not None and self._last_exam.passed
|
|
186
|
+
weight_stable = self._last_drift is None or not self._last_drift.is_significant
|
|
187
|
+
q = get_quarantine_status(self.model_id, registry=self._registry)
|
|
188
|
+
quarantined = q.is_quarantined
|
|
189
|
+
|
|
190
|
+
if not force:
|
|
191
|
+
issues = []
|
|
192
|
+
if not last_passed:
|
|
193
|
+
issues.append("last physical exam did not pass (or no exam on record)")
|
|
194
|
+
if quarantined:
|
|
195
|
+
issues.append("model is under quarantine")
|
|
196
|
+
if not weight_stable:
|
|
197
|
+
issues.append("weight drift detected")
|
|
198
|
+
if issues:
|
|
199
|
+
raise ValueError(
|
|
200
|
+
f"Cannot issue health certificate for {self.model_id}: "
|
|
201
|
+
+ "; ".join(issues)
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
now = time.time()
|
|
205
|
+
return HealthCertificate(
|
|
206
|
+
model_id=self.model_id,
|
|
207
|
+
status=self.status,
|
|
208
|
+
issued_at=now,
|
|
209
|
+
expires_at=now + self._certificate_ttl,
|
|
210
|
+
last_exam_passed=last_passed,
|
|
211
|
+
weight_stable=weight_stable,
|
|
212
|
+
quarantine_active=quarantined,
|
|
213
|
+
notes="Issued by Vetcheck" if last_passed and not quarantined else "Force-issued",
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _default_exam_suite() -> list[dict[str, Any]]:
|
|
218
|
+
"""Default vital signs checked during a physical exam."""
|
|
219
|
+
return [
|
|
220
|
+
{"name": "temperature", "description": "Edge case handling", "critical": True},
|
|
221
|
+
{"name": "heart_rate", "description": "Response latency within bounds", "critical": True},
|
|
222
|
+
{"name": "blood_pressure", "description": "Load handling without degradation", "critical": False},
|
|
223
|
+
{"name": "reflexes", "description": "Function calling and structured output", "critical": True},
|
|
224
|
+
{"name": "vision", "description": "Context window utilization", "critical": False},
|
|
225
|
+
]
|
vetcheck/drift.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Drift module — output drift detection over time (weight monitoring).
|
|
3
|
+
|
|
4
|
+
Like weighing a dog at every visit, this compares recent model
|
|
5
|
+
outputs against an established baseline to detect statistically
|
|
6
|
+
significant drift.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import math
|
|
12
|
+
import time
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from statistics import mean, pstdev
|
|
18
|
+
|
|
19
|
+
_HAS_STATS = True
|
|
20
|
+
except ImportError:
|
|
21
|
+
_HAS_STATS = False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class DriftReport:
|
|
26
|
+
"""
|
|
27
|
+
Weight check results — drift report for a model.
|
|
28
|
+
|
|
29
|
+
Like a vet's weight log, tracking whether the model's
|
|
30
|
+
outputs have shifted from the baseline.
|
|
31
|
+
"""
|
|
32
|
+
model_id: str
|
|
33
|
+
baseline_mean: float
|
|
34
|
+
recent_mean: float
|
|
35
|
+
drift_score: float
|
|
36
|
+
threshold: float
|
|
37
|
+
is_significant: bool
|
|
38
|
+
trend: str # "stable", "increasing", "decreasing"
|
|
39
|
+
timestamp: float = field(default_factory=time.time)
|
|
40
|
+
sample_size: int = 0
|
|
41
|
+
|
|
42
|
+
def summary(self) -> str:
|
|
43
|
+
icon = "✅" if not self.is_significant else "⚖️"
|
|
44
|
+
return (
|
|
45
|
+
f"{icon} Weight Check for {self.model_id}\n"
|
|
46
|
+
f" Baseline: {self.baseline_mean:.4f}\n"
|
|
47
|
+
f" Recent: {self.recent_mean:.4f}\n"
|
|
48
|
+
f" Drift: {self.drift_score:.4f} (threshold: {self.threshold:.4f})\n"
|
|
49
|
+
f" Trend: {self.trend}\n"
|
|
50
|
+
f" Verdict: {'SIGNIFICANT DRIFT' if self.is_significant else 'Within normal range'}"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def to_dict(self) -> dict[str, Any]:
|
|
54
|
+
return {
|
|
55
|
+
"model_id": self.model_id,
|
|
56
|
+
"baseline_mean": self.baseline_mean,
|
|
57
|
+
"recent_mean": self.recent_mean,
|
|
58
|
+
"drift_score": self.drift_score,
|
|
59
|
+
"threshold": self.threshold,
|
|
60
|
+
"is_significant": self.is_significant,
|
|
61
|
+
"trend": self.trend,
|
|
62
|
+
"timestamp": self.timestamp,
|
|
63
|
+
"sample_size": self.sample_size,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _extract_metric(output: dict[str, Any], key: str = "score") -> float:
|
|
68
|
+
"""Extract a numeric metric from an output dict."""
|
|
69
|
+
if key in output:
|
|
70
|
+
return float(output[key])
|
|
71
|
+
# Try common alternatives
|
|
72
|
+
for k in ("value", "metric", "confidence", "loss", "accuracy"):
|
|
73
|
+
if k in output:
|
|
74
|
+
return float(output[k])
|
|
75
|
+
return 0.0
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def check_weight_drift(
|
|
79
|
+
model_id: str,
|
|
80
|
+
baseline: list[dict[str, Any]],
|
|
81
|
+
recent: list[dict[str, Any]],
|
|
82
|
+
metric_key: str = "score",
|
|
83
|
+
threshold: float = 0.05,
|
|
84
|
+
) -> DriftReport:
|
|
85
|
+
"""
|
|
86
|
+
Compare recent outputs to baseline — the weight check.
|
|
87
|
+
|
|
88
|
+
Uses a simple statistical comparison: the absolute difference
|
|
89
|
+
of means relative to the baseline standard deviation, similar
|
|
90
|
+
to a Cohen's d effect size.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
model_id: The model being weighed.
|
|
94
|
+
baseline: Historical output samples (the established weight).
|
|
95
|
+
recent: Recent output samples (the current weight).
|
|
96
|
+
metric_key: Key to extract the numeric metric from each sample.
|
|
97
|
+
threshold: Drift score above which drift is "significant".
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
DriftReport with the assessment.
|
|
101
|
+
"""
|
|
102
|
+
baseline_values = [_extract_metric(o, metric_key) for o in baseline] if baseline else [0.0]
|
|
103
|
+
recent_values = [_extract_metric(o, metric_key) for o in recent] if recent else [0.0]
|
|
104
|
+
|
|
105
|
+
b_mean = mean(baseline_values) if _HAS_STATS else sum(baseline_values) / len(baseline_values)
|
|
106
|
+
r_mean = mean(recent_values) if _HAS_STATS else sum(recent_values) / len(recent_values)
|
|
107
|
+
|
|
108
|
+
b_std = pstdev(baseline_values) if len(baseline_values) > 1 and _HAS_STATS else 0.0001
|
|
109
|
+
b_std = max(b_std, 1e-6) # avoid division by zero
|
|
110
|
+
|
|
111
|
+
# Cohen's d-style drift score
|
|
112
|
+
drift_score = abs(r_mean - b_mean) / b_std
|
|
113
|
+
|
|
114
|
+
is_significant = drift_score > threshold
|
|
115
|
+
|
|
116
|
+
# Trend determination
|
|
117
|
+
if abs(drift_score) < threshold * 0.5:
|
|
118
|
+
trend = "stable"
|
|
119
|
+
elif r_mean > b_mean:
|
|
120
|
+
trend = "increasing"
|
|
121
|
+
else:
|
|
122
|
+
trend = "decreasing"
|
|
123
|
+
|
|
124
|
+
return DriftReport(
|
|
125
|
+
model_id=model_id,
|
|
126
|
+
baseline_mean=b_mean,
|
|
127
|
+
recent_mean=r_mean,
|
|
128
|
+
drift_score=drift_score,
|
|
129
|
+
threshold=threshold,
|
|
130
|
+
is_significant=is_significant,
|
|
131
|
+
trend=trend,
|
|
132
|
+
sample_size=len(recent_values),
|
|
133
|
+
)
|
vetcheck/exam.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Exam module — regression test runner as health check (physical exam).
|
|
3
|
+
|
|
4
|
+
Each test is a vital sign. The runner executes them and produces
|
|
5
|
+
an ExamResult with a full health assessment.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import time
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import Any, Callable
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class VitalSign:
|
|
17
|
+
"""A single test result — one vital sign from the physical."""
|
|
18
|
+
name: str
|
|
19
|
+
description: str
|
|
20
|
+
critical: bool
|
|
21
|
+
passed: bool
|
|
22
|
+
duration_ms: float = 0.0
|
|
23
|
+
error: str | None = None
|
|
24
|
+
details: dict[str, Any] = field(default_factory=dict)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class ExamResult:
|
|
29
|
+
"""Full results of a physical exam — the vet's report."""
|
|
30
|
+
model_id: str
|
|
31
|
+
vitals: list[VitalSign] = field(default_factory=list)
|
|
32
|
+
timestamp: float = field(default_factory=time.time)
|
|
33
|
+
duration_ms: float = 0.0
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def passed(self) -> bool:
|
|
37
|
+
"""Overall pass — no critical vital signs failed."""
|
|
38
|
+
return all(v.passed for v in self.vitals if v.critical)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def all_passed(self) -> bool:
|
|
42
|
+
"""Every vital sign passed, including non-critical."""
|
|
43
|
+
return all(v.passed for v in self.vitals)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def critical_failures(self) -> int:
|
|
47
|
+
return sum(1 for v in self.vitals if v.critical and not v.passed)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def warnings(self) -> int:
|
|
51
|
+
return sum(1 for v in self.vitals if not v.critical and not v.passed)
|
|
52
|
+
|
|
53
|
+
def summary(self) -> str:
|
|
54
|
+
"""Human-readable summary — like the vet's notes."""
|
|
55
|
+
lines = [
|
|
56
|
+
f"📋 Physical Exam Report for {self.model_id}",
|
|
57
|
+
f" Date: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime(self.timestamp))}",
|
|
58
|
+
f" Duration: {self.duration_ms:.1f}ms",
|
|
59
|
+
f" Overall: {'✅ PASSED' if self.passed else '❌ FAILED'}",
|
|
60
|
+
"",
|
|
61
|
+
]
|
|
62
|
+
for v in self.vitals:
|
|
63
|
+
icon = "✅" if v.passed else ("🚨" if v.critical else "⚠️")
|
|
64
|
+
tag = " [CRITICAL]" if v.critical else " [warning]" if not v.passed else ""
|
|
65
|
+
lines.append(f" {icon} {v.name}{tag} — {v.description}")
|
|
66
|
+
if v.error:
|
|
67
|
+
lines.append(f" Error: {v.error}")
|
|
68
|
+
lines.append("")
|
|
69
|
+
lines.append(
|
|
70
|
+
f" Critical failures: {self.critical_failures} | Warnings: {self.warnings}"
|
|
71
|
+
)
|
|
72
|
+
return "\n".join(lines)
|
|
73
|
+
|
|
74
|
+
def to_dict(self) -> dict[str, Any]:
|
|
75
|
+
return {
|
|
76
|
+
"model_id": self.model_id,
|
|
77
|
+
"timestamp": self.timestamp,
|
|
78
|
+
"duration_ms": self.duration_ms,
|
|
79
|
+
"passed": self.passed,
|
|
80
|
+
"all_passed": self.all_passed,
|
|
81
|
+
"critical_failures": self.critical_failures,
|
|
82
|
+
"warnings": self.warnings,
|
|
83
|
+
"vitals": [
|
|
84
|
+
{
|
|
85
|
+
"name": v.name,
|
|
86
|
+
"description": v.description,
|
|
87
|
+
"critical": v.critical,
|
|
88
|
+
"passed": v.passed,
|
|
89
|
+
"duration_ms": v.duration_ms,
|
|
90
|
+
"error": v.error,
|
|
91
|
+
"details": v.details,
|
|
92
|
+
}
|
|
93
|
+
for v in self.vitals
|
|
94
|
+
],
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def run_physical_exam(
|
|
99
|
+
model_id: str,
|
|
100
|
+
suite: list[dict[str, Any]],
|
|
101
|
+
runner: Callable[[dict[str, Any]], bool] | None = None,
|
|
102
|
+
) -> ExamResult:
|
|
103
|
+
"""
|
|
104
|
+
Execute the regression suite as a physical exam.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
model_id: The model being examined.
|
|
108
|
+
suite: List of test definitions. Each must have:
|
|
109
|
+
- name: vital sign name
|
|
110
|
+
- description: what it checks
|
|
111
|
+
- critical: whether failure means quarantine
|
|
112
|
+
- check (optional): a callable that returns bool
|
|
113
|
+
runner: Optional custom runner. If None, uses default which
|
|
114
|
+
calls each test's "check" callable or defaults to pass.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
ExamResult with all vital signs recorded.
|
|
118
|
+
"""
|
|
119
|
+
start = time.time()
|
|
120
|
+
vitals: list[VitalSign] = []
|
|
121
|
+
|
|
122
|
+
for test in suite:
|
|
123
|
+
name = test.get("name", "unknown")
|
|
124
|
+
desc = test.get("description", "")
|
|
125
|
+
critical = test.get("critical", False)
|
|
126
|
+
check = test.get("check")
|
|
127
|
+
|
|
128
|
+
v_start = time.time()
|
|
129
|
+
passed = True
|
|
130
|
+
error = None
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
if runner is not None:
|
|
134
|
+
passed = bool(runner(test))
|
|
135
|
+
elif check is not None:
|
|
136
|
+
passed = bool(check())
|
|
137
|
+
# If no runner and no check, default to pass (assume external)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
passed = False
|
|
140
|
+
error = str(e)
|
|
141
|
+
|
|
142
|
+
v_duration = (time.time() - v_start) * 1000
|
|
143
|
+
|
|
144
|
+
vitals.append(
|
|
145
|
+
VitalSign(
|
|
146
|
+
name=name,
|
|
147
|
+
description=desc,
|
|
148
|
+
critical=critical,
|
|
149
|
+
passed=passed,
|
|
150
|
+
duration_ms=v_duration,
|
|
151
|
+
error=error,
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
total_duration = (time.time() - start) * 1000
|
|
156
|
+
|
|
157
|
+
return ExamResult(
|
|
158
|
+
model_id=model_id,
|
|
159
|
+
vitals=vitals,
|
|
160
|
+
duration_ms=total_duration,
|
|
161
|
+
)
|
vetcheck/quarantine.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Quarantine module — isolation and release for sick models.
|
|
3
|
+
|
|
4
|
+
When a model fails a critical exam, it gets quarantined.
|
|
5
|
+
Traffic is routed elsewhere until it passes a clean physical
|
|
6
|
+
and is explicitly released.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from enum import Enum
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class QuarantineState(str, Enum):
|
|
18
|
+
"""State of a model in the quarantine system."""
|
|
19
|
+
ACTIVE = "active" # In quarantine
|
|
20
|
+
RELEASED = "released" # Released back to duty
|
|
21
|
+
NEVER_QUARANTINED = "never_quarantined"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class QuarantineStatus:
|
|
26
|
+
"""
|
|
27
|
+
Current quarantine status of a model — like a kennel record.
|
|
28
|
+
|
|
29
|
+
Tracks when and why a model was isolated, and whether it's
|
|
30
|
+
been released.
|
|
31
|
+
"""
|
|
32
|
+
model_id: str
|
|
33
|
+
state: QuarantineState = QuarantineState.NEVER_QUARANTINED
|
|
34
|
+
quarantined_at: float | None = None
|
|
35
|
+
released_at: float | None = None
|
|
36
|
+
reason: str = ""
|
|
37
|
+
history: list[dict[str, Any]] = field(default_factory=list)
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def is_quarantined(self) -> bool:
|
|
41
|
+
"""Is this model currently in quarantine?"""
|
|
42
|
+
return self.state == QuarantineState.ACTIVE
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def duration(self) -> float | None:
|
|
46
|
+
"""How long has this model been in quarantine (seconds)?"""
|
|
47
|
+
if self.quarantined_at is None:
|
|
48
|
+
return None
|
|
49
|
+
end = self.released_at or time.time()
|
|
50
|
+
return end - self.quarantined_at
|
|
51
|
+
|
|
52
|
+
def summary(self) -> str:
|
|
53
|
+
icon = "🔒" if self.is_quarantined else "🟢"
|
|
54
|
+
lines = [f"{icon} Quarantine Status for {self.model_id}"]
|
|
55
|
+
lines.append(f" State: {self.state.value}")
|
|
56
|
+
|
|
57
|
+
if self.quarantined_at:
|
|
58
|
+
lines.append(
|
|
59
|
+
f" Quarantined: {time.strftime('%Y-%m-%d %H:%M UTC', time.gmtime(self.quarantined_at))}"
|
|
60
|
+
)
|
|
61
|
+
lines.append(f" Reason: {self.reason}")
|
|
62
|
+
if self.is_quarantined and self.duration is not None:
|
|
63
|
+
lines.append(f" Duration: {self.duration:.0f}s")
|
|
64
|
+
|
|
65
|
+
if self.released_at:
|
|
66
|
+
lines.append(
|
|
67
|
+
f" Released: {time.strftime('%Y-%m-%d %H:%M UTC', time.gmtime(self.released_at))}"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if self.history:
|
|
71
|
+
lines.append(f" History: {len(self.history)} previous event(s)")
|
|
72
|
+
|
|
73
|
+
return "\n".join(lines)
|
|
74
|
+
|
|
75
|
+
def to_dict(self) -> dict[str, Any]:
|
|
76
|
+
return {
|
|
77
|
+
"model_id": self.model_id,
|
|
78
|
+
"state": self.state.value,
|
|
79
|
+
"quarantined_at": self.quarantined_at,
|
|
80
|
+
"released_at": self.released_at,
|
|
81
|
+
"reason": self.reason,
|
|
82
|
+
"duration": self.duration,
|
|
83
|
+
"history": self.history,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# In-memory registry (shared across VetCheck instances in same process)
|
|
88
|
+
_registry: dict[str, QuarantineStatus] = {}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _get_or_create(model_id: str, registry: dict[str, Any] | None = None) -> QuarantineStatus:
|
|
92
|
+
"""Get existing status or create a fresh one."""
|
|
93
|
+
reg = registry if registry is not None else _registry
|
|
94
|
+
if model_id not in reg:
|
|
95
|
+
reg[model_id] = QuarantineStatus(model_id=model_id)
|
|
96
|
+
return reg[model_id]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def quarantine_model(
|
|
100
|
+
model_id: str,
|
|
101
|
+
reason: str,
|
|
102
|
+
registry: dict[str, Any] | None = None,
|
|
103
|
+
) -> QuarantineStatus:
|
|
104
|
+
"""
|
|
105
|
+
Put a model into quarantine — isolate it from production.
|
|
106
|
+
|
|
107
|
+
Records the reason and timestamp. If already quarantined,
|
|
108
|
+
updates the reason but doesn't create a new record.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
model_id: The model to quarantine.
|
|
112
|
+
reason: Why it's being quarantined.
|
|
113
|
+
registry: Optional custom registry (for testing/isolation).
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Updated QuarantineStatus.
|
|
117
|
+
"""
|
|
118
|
+
status = _get_or_create(model_id, registry)
|
|
119
|
+
|
|
120
|
+
now = time.time()
|
|
121
|
+
|
|
122
|
+
# Record history if re-quarantining or state changes
|
|
123
|
+
if status.state != QuarantineState.ACTIVE:
|
|
124
|
+
status.history.append({
|
|
125
|
+
"event": "quarantined",
|
|
126
|
+
"timestamp": now,
|
|
127
|
+
"reason": reason,
|
|
128
|
+
"previous_state": status.state.value,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
status.state = QuarantineState.ACTIVE
|
|
132
|
+
status.quarantined_at = now
|
|
133
|
+
status.released_at = None
|
|
134
|
+
status.reason = reason
|
|
135
|
+
|
|
136
|
+
return status
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def release_model(
|
|
140
|
+
model_id: str,
|
|
141
|
+
registry: dict[str, Any] | None = None,
|
|
142
|
+
) -> QuarantineStatus:
|
|
143
|
+
"""
|
|
144
|
+
Release a model from quarantine — return it to active duty.
|
|
145
|
+
|
|
146
|
+
The model must be in quarantine. Records the release timestamp.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
model_id: The model to release.
|
|
150
|
+
registry: Optional custom registry.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
Updated QuarantineStatus.
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
ValueError: If the model is not currently quarantined.
|
|
157
|
+
"""
|
|
158
|
+
status = _get_or_create(model_id, registry)
|
|
159
|
+
|
|
160
|
+
if status.state != QuarantineState.ACTIVE:
|
|
161
|
+
raise ValueError(
|
|
162
|
+
f"Cannot release {model_id}: not in quarantine (state={status.state.value})"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
now = time.time()
|
|
166
|
+
status.history.append({
|
|
167
|
+
"event": "released",
|
|
168
|
+
"timestamp": now,
|
|
169
|
+
"duration": status.duration,
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
status.state = QuarantineState.RELEASED
|
|
173
|
+
status.released_at = now
|
|
174
|
+
|
|
175
|
+
return status
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def get_quarantine_status(
|
|
179
|
+
model_id: str,
|
|
180
|
+
registry: dict[str, Any] | None = None,
|
|
181
|
+
) -> QuarantineStatus:
|
|
182
|
+
"""
|
|
183
|
+
Check the quarantine status of a model.
|
|
184
|
+
|
|
185
|
+
Returns the current status, creating a fresh "never quarantined"
|
|
186
|
+
record if the model has never been seen.
|
|
187
|
+
"""
|
|
188
|
+
return _get_or_create(model_id, registry)
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vetcheck
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Model health monitoring as veterinary care — regression tests as physical exams, drift detection as weight monitoring, auto-quarantine on critical health breaches.
|
|
5
|
+
Author: SuperInstance
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/SuperInstance/vetcheck
|
|
8
|
+
Project-URL: Repository, https://github.com/SuperInstance/vetcheck
|
|
9
|
+
Keywords: ml,monitoring,model-health,drift-detection,regression-testing,observability
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Testing
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# Vetcheck: Model Health Monitoring as Veterinary Care
|
|
25
|
+
|
|
26
|
+
> Working dogs need regular checkups. So do models.
|
|
27
|
+
|
|
28
|
+
[](https://python.org)
|
|
29
|
+
[](LICENSE)
|
|
30
|
+
[](tests/)
|
|
31
|
+
|
|
32
|
+
A model that passed regression tests six months ago might silently degrade over time — distribution drift, fine-tuning side effects, dependency changes. Vetcheck treats model health monitoring like veterinary care because in the Working Animal Architecture paradigm, every model is a working animal that needs ongoing supervision to stay fit for duty. Physical exams catch regressions. Weight monitoring catches output drift. Quarantine isolates failures before they reach production.
|
|
33
|
+
|
|
34
|
+
## What It Does
|
|
35
|
+
|
|
36
|
+
Vetcheck provides three core exams and two lifecycle operations. The **physical exam** runs a full regression test suite against the model, checking vital signs: does it still handle edge cases (temperature), are response times within bounds (heart rate), does it handle load without degradation (blood pressure), do function-calling and structured outputs still work (reflexes)? The result is an `ExamResult` with pass/fail per test and an overall `HealthStatus`.
|
|
37
|
+
|
|
38
|
+
The **weight check** monitors output distribution drift over time. Just as a vet weighs a dog at every visit and flags concerning changes, Vetcheck compares recent output embeddings or distributions to a baseline and flags statistically significant drift. Trends are tracked across checkups — a gradual 5% drift over a month is different from a sudden 20% shift overnight.
|
|
39
|
+
|
|
40
|
+
When a model fails critically, **quarantine** auto-isolates it: traffic is routed elsewhere, alerts fire, and the model stays isolated until a clean physical exam passes. The **health certificate** is a signed attestation that a model is fit for production — it verifies the last physical exam passed, confirms no active quarantine, checks weight stability, and returns a certificate with an expiry date.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install vetcheck
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For development:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/SuperInstance/vetcheck.git
|
|
52
|
+
cd vetcheck
|
|
53
|
+
pip install -e ".[dev]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from vetcheck import VetCheck
|
|
60
|
+
|
|
61
|
+
vet = VetCheck(model_id="llama-3-70b")
|
|
62
|
+
|
|
63
|
+
# Run a full physical — executes regression suite
|
|
64
|
+
report = vet.physical_exam()
|
|
65
|
+
print(report.summary())
|
|
66
|
+
# ════════════════════════════════════════════
|
|
67
|
+
# PHYSICAL EXAM: llama-3-70b
|
|
68
|
+
# Overall: HEALTHY
|
|
69
|
+
# Tests: 47 passed, 3 failed, 0 skipped
|
|
70
|
+
# ════════════════════════════════════════════
|
|
71
|
+
|
|
72
|
+
# Check for weight drift — compares recent outputs to baseline
|
|
73
|
+
drift = vet.weight_check(window=100)
|
|
74
|
+
if drift.significant:
|
|
75
|
+
print(f"⚠ Drift detected: {drift.magnitude:.1%} from baseline")
|
|
76
|
+
print(f" Trend: {drift.trend}") # "increasing", "decreasing", "stable"
|
|
77
|
+
else:
|
|
78
|
+
print("✓ Weight stable")
|
|
79
|
+
|
|
80
|
+
# Quarantine a sick model
|
|
81
|
+
if report.critical_failures > 0:
|
|
82
|
+
vet.quarantine(reason="Critical regression detected")
|
|
83
|
+
print("Model quarantined — traffic routed to backup")
|
|
84
|
+
|
|
85
|
+
# ... after fixes applied ...
|
|
86
|
+
|
|
87
|
+
# Run physical again to verify recovery
|
|
88
|
+
recovery = vet.physical_exam()
|
|
89
|
+
if recovery.passed:
|
|
90
|
+
vet.release()
|
|
91
|
+
print("Model returned to active duty")
|
|
92
|
+
|
|
93
|
+
# Issue a clean bill of health
|
|
94
|
+
cert = vet.health_certificate()
|
|
95
|
+
print(f"Health certificate issued, expires: {cert.expires_at}")
|
|
96
|
+
print(f"Valid: {cert.is_valid()}")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Architecture
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
src/vetcheck/
|
|
103
|
+
├── __init__.py # VetCheck orchestrator + HealthCertificate
|
|
104
|
+
├── exam.py # Regression test runner (physical exams)
|
|
105
|
+
│ ├── run_physical_exam()
|
|
106
|
+
│ ├── ExamResult
|
|
107
|
+
│ └── TestCase / TestSuite
|
|
108
|
+
├── drift.py # Output drift detection (weight monitoring)
|
|
109
|
+
│ ├── check_weight_drift()
|
|
110
|
+
│ ├── DriftReport
|
|
111
|
+
│ └── BaselineDistribution
|
|
112
|
+
└── quarantine.py # Quarantine and release system
|
|
113
|
+
├── quarantine_model()
|
|
114
|
+
├── release_model()
|
|
115
|
+
├── get_quarantine_status()
|
|
116
|
+
└── QuarantineStatus
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Health States
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
HEALTHY ──────▶ UNDER_OBSERVATION ──────▶ QUARANTINED
|
|
123
|
+
▲ │ │
|
|
124
|
+
│ │ │
|
|
125
|
+
└────────────────────┘ │
|
|
126
|
+
release() (clean exam) │
|
|
127
|
+
▲ │
|
|
128
|
+
└────────────────────────────────────────────┘
|
|
129
|
+
release() (clean exam)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## API Reference
|
|
133
|
+
|
|
134
|
+
### `VetCheck`
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
class VetCheck:
|
|
138
|
+
def __init__(self, model_id: str, baseline_dir: str = "./baselines")
|
|
139
|
+
|
|
140
|
+
# Exams
|
|
141
|
+
def physical_exam(self, suite: str = "default") -> ExamResult
|
|
142
|
+
def weight_check(self, window: int = 100) -> DriftReport
|
|
143
|
+
|
|
144
|
+
# Lifecycle
|
|
145
|
+
def quarantine(self, reason: str) -> QuarantineStatus
|
|
146
|
+
def release(self) -> bool
|
|
147
|
+
@property
|
|
148
|
+
def is_quarantined(self) -> bool
|
|
149
|
+
|
|
150
|
+
# Certification
|
|
151
|
+
def health_certificate(self, validity_days: int = 7) -> HealthCertificate
|
|
152
|
+
@property
|
|
153
|
+
def health_status(self) -> HealthStatus
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Result Types
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
@dataclass
|
|
160
|
+
class ExamResult:
|
|
161
|
+
model_id: str
|
|
162
|
+
passed: bool
|
|
163
|
+
overall_status: HealthStatus
|
|
164
|
+
tests_passed: int
|
|
165
|
+
tests_failed: int
|
|
166
|
+
critical_failures: int
|
|
167
|
+
duration_seconds: float
|
|
168
|
+
details: list[TestResult]
|
|
169
|
+
|
|
170
|
+
@dataclass
|
|
171
|
+
class DriftReport:
|
|
172
|
+
model_id: str
|
|
173
|
+
significant: bool # statistically significant drift
|
|
174
|
+
magnitude: float # 0.0-1.0
|
|
175
|
+
trend: str # "increasing", "decreasing", "stable"
|
|
176
|
+
window: int # samples compared
|
|
177
|
+
p_value: float # statistical test result
|
|
178
|
+
|
|
179
|
+
@dataclass
|
|
180
|
+
class HealthCertificate:
|
|
181
|
+
model_id: str
|
|
182
|
+
status: HealthStatus
|
|
183
|
+
issued_at: float
|
|
184
|
+
expires_at: float
|
|
185
|
+
last_exam_passed: bool
|
|
186
|
+
weight_stable: bool
|
|
187
|
+
quarantine_active: bool
|
|
188
|
+
notes: str
|
|
189
|
+
|
|
190
|
+
def is_valid(self, now: float | None = None) -> bool
|
|
191
|
+
def to_dict(self) -> dict
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### `HealthStatus`
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
class HealthStatus(str, Enum):
|
|
198
|
+
HEALTHY = "healthy"
|
|
199
|
+
UNDER_OBSERVATION = "under_observation"
|
|
200
|
+
QUARANTINED = "quarantined"
|
|
201
|
+
CRITICAL = "critical"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## The Analogy
|
|
205
|
+
|
|
206
|
+
| Veterinary Care | Vetcheck |
|
|
207
|
+
|-----------------|----------|
|
|
208
|
+
| Physical exam | Regression test suite (`physical_exam`) |
|
|
209
|
+
| Weight monitoring | Output drift detection (`weight_check`) |
|
|
210
|
+
| Quarantine | Auto-isolation on critical health breach |
|
|
211
|
+
| Health certificate | Clearance for production deployment |
|
|
212
|
+
| Vaccination schedule | Periodic exam scheduling |
|
|
213
|
+
| Breed-specific screening | Model-specific test suites |
|
|
214
|
+
|
|
215
|
+
## Testing
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
pip install -e ".[dev]"
|
|
219
|
+
pytest tests/ -v
|
|
220
|
+
|
|
221
|
+
# Test exam runner
|
|
222
|
+
pytest tests/test_exam.py -v
|
|
223
|
+
|
|
224
|
+
# Test drift detection
|
|
225
|
+
pytest tests/test_drift.py -v
|
|
226
|
+
|
|
227
|
+
# Test quarantine lifecycle
|
|
228
|
+
pytest tests/test_quarantine.py -v
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Philosophy
|
|
232
|
+
|
|
233
|
+
In animal husbandry, preventative medicine is cheaper than emergency treatment. The same applies to AI systems: catching a regression before it reaches production is dramatically cheaper than responding to an outage. Vetcheck brings the discipline of veterinary preventative care to model operations — regular checkups, early detection, isolation of sick individuals, and structured health certificates before deployment.
|
|
234
|
+
|
|
235
|
+
This is part of [Working Animal Architecture](https://github.com/SuperInstance/AI-Writings) — specifically the health monitoring layer that keeps the kennel (flux registry) populated with animals fit for duty. A model with an expired health certificate shouldn't be in production, just as a working dog that hasn't seen a vet in a year shouldn't be herding sheep.
|
|
236
|
+
|
|
237
|
+
## Ecosystem
|
|
238
|
+
|
|
239
|
+
| Repo | Role |
|
|
240
|
+
|------|------|
|
|
241
|
+
| **[vetcheck](https://github.com/SuperInstance/vetcheck)** | **This repo** — health monitoring |
|
|
242
|
+
| [shepherds-console](https://github.com/SuperInstance/shepherds-console) | Dashboard (displays vetcheck health status) |
|
|
243
|
+
| [breed-registry](https://github.com/SuperInstance/breed-registry) | Breed selection (uses health certificates) |
|
|
244
|
+
| [lineage-tracker](https://github.com/SuperInstance/lineage-tracker) | Lineage (health data enriches lineage records) |
|
|
245
|
+
| [baton](https://github.com/SuperInstance/baton) | Generational handoff (health informs sunset decisions) |
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
## Integration Patterns
|
|
250
|
+
|
|
251
|
+
### With Breed Registry: Pre-Deployment Health Check
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from vetcheck import VetCheck
|
|
255
|
+
from breed_registry import select_breed
|
|
256
|
+
|
|
257
|
+
# Select the best model for a task
|
|
258
|
+
recommended = select_breed("code_generation")
|
|
259
|
+
print(f"Recommended: {recommended.recommended}")
|
|
260
|
+
|
|
261
|
+
# Before deploying, verify it's healthy
|
|
262
|
+
vet = VetCheck(model_id=recommended.recommended)
|
|
263
|
+
cert = vet.health_certificate(validity_days=14)
|
|
264
|
+
|
|
265
|
+
if cert.is_valid():
|
|
266
|
+
print(f"✓ {recommended.recommended} is certified healthy — deploy")
|
|
267
|
+
else:
|
|
268
|
+
print(f"✗ {recommended.recommended} failed health check")
|
|
269
|
+
print(f" Falling back to alternatives...")
|
|
270
|
+
for alt in recommended.alternatives:
|
|
271
|
+
alt_vet = VetCheck(model_id=alt.breed)
|
|
272
|
+
alt_cert = alt_vet.health_certificate()
|
|
273
|
+
if alt_cert.is_valid():
|
|
274
|
+
print(f" ✓ {alt.breed} is healthy (score: {alt.score:.1f})")
|
|
275
|
+
break
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### With Lineage Tracker: Regression Source Detection
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
from vetcheck import VetCheck
|
|
282
|
+
from lineage_tracker import LineageTracker
|
|
283
|
+
|
|
284
|
+
# Model failed its physical exam
|
|
285
|
+
vet = VetCheck(model_id="prod-model-v7")
|
|
286
|
+
report = vet.physical_exam()
|
|
287
|
+
|
|
288
|
+
if not report.passed:
|
|
289
|
+
# Check if this is a known weakness in the lineage
|
|
290
|
+
tracker = LineageTracker("lineage.json")
|
|
291
|
+
lineage = tracker.get_lineage("prod-model-v7")
|
|
292
|
+
|
|
293
|
+
print("Failed exam. Checking lineage for inherited weaknesses:")
|
|
294
|
+
for gen in lineage:
|
|
295
|
+
model = gen.model
|
|
296
|
+
failed_areas = [t.name for t in report.details if not t.passed]
|
|
297
|
+
for area in failed_areas:
|
|
298
|
+
trait_key = area.lower().replace(" ", "_")
|
|
299
|
+
if model.traits and trait_key in model.traits:
|
|
300
|
+
print(f" Gen {gen.generation} {model.name}: {trait_key}={model.traits[trait_key]}")
|
|
301
|
+
|
|
302
|
+
# If the weakness is inherited, quarantine and recommend retraining
|
|
303
|
+
vet.quarantine(reason=f"Inherited regression: {failed_areas}")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Continuous Monitoring with Scheduled Exams
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
from vetcheck import VetCheck
|
|
310
|
+
import schedule # pip install schedule
|
|
311
|
+
import time
|
|
312
|
+
|
|
313
|
+
vet = VetCheck(model_id="prod-model-v7", baseline_dir="./baselines")
|
|
314
|
+
|
|
315
|
+
# Daily weight check (lightweight — compares output distributions)
|
|
316
|
+
schedule.every().day.at("06:00").do(lambda: vet.weight_check(window=500))
|
|
317
|
+
|
|
318
|
+
# Weekly physical (full regression suite)
|
|
319
|
+
schedule.every().monday.at("02:00").do(lambda: vet.physical_exam())
|
|
320
|
+
|
|
321
|
+
# Monthly health certificate renewal
|
|
322
|
+
schedule.every(30).days.do(lambda: vet.health_certificate(validity_days=7))
|
|
323
|
+
|
|
324
|
+
# Auto-quarantine on critical failure
|
|
325
|
+
def full_checkup():
|
|
326
|
+
report = vet.physical_exam()
|
|
327
|
+
if report.critical_failures > 0:
|
|
328
|
+
vet.quarantine(reason=f"Auto-quarantine: {report.critical_failures} critical failures")
|
|
329
|
+
# Alert the team
|
|
330
|
+
print(f"🚨 {vet.model_id} QUARANTINED — {report.critical_failures} critical failures")
|
|
331
|
+
return report
|
|
332
|
+
|
|
333
|
+
schedule.every().day.at("12:00").do(full_checkup)
|
|
334
|
+
|
|
335
|
+
# Run the scheduler
|
|
336
|
+
while True:
|
|
337
|
+
schedule.run_pending()
|
|
338
|
+
time.sleep(60)
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Fleet Health Dashboard
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
from vetcheck import VetCheck
|
|
345
|
+
from breed_registry import BreedMatcher
|
|
346
|
+
|
|
347
|
+
matcher = BreedMatcher()
|
|
348
|
+
fleet = ["gpt-4", "claude-3", "llama-3", "glm", "qwen"]
|
|
349
|
+
|
|
350
|
+
print("FLEET HEALTH REPORT")
|
|
351
|
+
print("=" * 60)
|
|
352
|
+
|
|
353
|
+
for model_id in fleet:
|
|
354
|
+
vet = VetCheck(model_id=model_id)
|
|
355
|
+
status = vet.health_status
|
|
356
|
+
quarantined = "🔒 QUARANTINED" if vet.is_quarantined else "🟢 ACTIVE"
|
|
357
|
+
|
|
358
|
+
# Quick weight check
|
|
359
|
+
drift = vet.weight_check(window=100)
|
|
360
|
+
drift_indicator = "📉" if drift.significant else "✓"
|
|
361
|
+
|
|
362
|
+
print(f" {model_id:15s} {status.value:20s} {quarantined} drift:{drift_indicator}")
|
|
363
|
+
|
|
364
|
+
# Recommend breed-specific action
|
|
365
|
+
aptitude = matcher.assess(model_id, "reasoning")
|
|
366
|
+
if status.value == "quarantined":
|
|
367
|
+
alternatives = matcher.select("reasoning").alternatives[:2]
|
|
368
|
+
print(f" → Failover to: {[a.breed for a in alternatives]}")
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Monitoring Philosophy
|
|
372
|
+
|
|
373
|
+
The veterinary metaphor runs deeper than naming. In real animal husbandry:
|
|
374
|
+
|
|
375
|
+
- **Preventative care is cheaper than emergency treatment.** A daily weight check catches drift before it becomes a regression. A weekly physical catches regressions before they reach users.
|
|
376
|
+
- **Quarantine is not punishment.** It's protection — for the model (no traffic to handle while recovering) and for the system (no degraded output reaching users). The quarantine is lifted the moment a clean physical passes.
|
|
377
|
+
- **Health certificates expire.** A model that was healthy last month might not be healthy today. Certificate expiry isn't bureaucracy — it's the acknowledgment that model health is dynamic, not static.
|
|
378
|
+
- **Breed-specific screening matters.** A Thoroughbred (GPT-4) needs different tests than a Mustang (Llama-3). Custom test suites per breed catch breed-specific failure modes that generic tests miss.
|
|
379
|
+
- **The vet's authority overrides the registry.** A model with the best breed score should not be in production if its health certificate has expired. The registry says what's best on paper; the vet says what's fit for duty right now.
|
|
380
|
+
|
|
381
|
+
## License
|
|
382
|
+
|
|
383
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
vetcheck/__init__.py,sha256=XKgcrg9wCFd6t0D3tXYx5RzO5sw8adu_XI_rW0UWTZs,7871
|
|
2
|
+
vetcheck/drift.py,sha256=KU9RyTQQhnaKuLmko3Cp53s2OycYwNgks0N6eM6kZNY,4206
|
|
3
|
+
vetcheck/exam.py,sha256=pwoJyMj4qdnwM2FHOY96QMfVqT243kkZ6u4OVtCatYA,5045
|
|
4
|
+
vetcheck/quarantine.py,sha256=vvSvJwuqTUKUWL37sdSQBYga27_gtLlY1xjglworIiU,5474
|
|
5
|
+
vetcheck-0.1.0.dist-info/licenses/LICENSE,sha256=oIZ4iMwyoGNfEZRn_qZ2bqd1wzV8oUQgjyS-ZAEDLEI,1070
|
|
6
|
+
vetcheck-0.1.0.dist-info/METADATA,sha256=7WymTyVTa3uNA0m6iDE2S_0fP1RxlxeeSha4ttMWxc0,14874
|
|
7
|
+
vetcheck-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
8
|
+
vetcheck-0.1.0.dist-info/top_level.txt,sha256=kAU5egbfyiDIm3UsljFnibIZykajIRDeAxvRECFCkwc,9
|
|
9
|
+
vetcheck-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SuperInstance
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
vetcheck
|