verilink-aiverify-plugin 1.0.0__tar.gz

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.
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2024 Rajinder Jhol
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.4
2
+ Name: verilink-aiverify-plugin
3
+ Version: 1.0.0
4
+ Summary: VeriLinkOS Active Governance Integration for AI Verify
5
+ License: Apache-2.0
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: httpx<0.28.0,>=0.23.0
10
+ Requires-Dist: pydantic<3.0.0,>=1.10.0
11
+ Requires-Dist: python-dotenv<2.1.0,>=0.19.0
12
+ Requires-Dist: tenacity<9.1.0,>=8.0.0
13
+ Dynamic: license-file
14
+ Dynamic: requires-python
15
+
16
+ # VeriLinkOS AI Verify Plugin
17
+
18
+ [![PyPI version](https://badge.fury.io/py/verilink-aiverify-plugin.svg)](https://badge.fury.io/py/verilink-aiverify-plugin)
19
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
20
+
21
+ ## Overview
22
+
23
+ VeriLinkOS AI Verify Plugin integrates active governance capabilities from VeriLinkOS into the AI Verify testing framework.
24
+
25
+ ### Features
26
+
27
+ - ✅ Active Governance: Real-time policy enforcement during AI tests
28
+ - ✅ VAP Receipts: Cryptographic evidence for compliance audits
29
+ - ✅ AI-BOM Verification: Ensure model integrity and provenance
30
+ - ✅ Trust Tokens: JIT authentication for each test run
31
+ - ✅ Predictive Enforcement: ML-based risk prediction
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pip install verilink-aiverify-plugin
37
+ ```
38
+
39
+ ## Configuration
40
+ Set environment variables:
41
+
42
+ ```bash
43
+ export VERILINK_API_URL=https://api.verilink.os
44
+ export VERILINK_API_KEY=your_api_key
45
+ export VERILINK_AGENT_ID=your_agent_id
46
+ export VERILINK_ORG_ID=your_org_id
47
+ ```
48
+
49
+ ## Quick Start
50
+ ```python
51
+ import asyncio
52
+ from verilink_plugin import VeriLinkGovernancePlugin
53
+
54
+ async def test_model():
55
+ plugin = VeriLinkGovernancePlugin()
56
+
57
+ result = await plugin.run_test(
58
+ {"model_id": "model-001", "dataset": "test-data"},
59
+ lambda config: {"passed": True, "artifacts": {}}
60
+ )
61
+
62
+ print(f"Passed: {result.passed}")
63
+ print(f"Receipt: {result.receipt_id}")
64
+
65
+ await plugin.cleanup()
66
+
67
+ asyncio.run(test_model())
68
+ ```
69
+
70
+ ## License
71
+ Apache 2.0
@@ -0,0 +1,56 @@
1
+ # VeriLinkOS AI Verify Plugin
2
+
3
+ [![PyPI version](https://badge.fury.io/py/verilink-aiverify-plugin.svg)](https://badge.fury.io/py/verilink-aiverify-plugin)
4
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
5
+
6
+ ## Overview
7
+
8
+ VeriLinkOS AI Verify Plugin integrates active governance capabilities from VeriLinkOS into the AI Verify testing framework.
9
+
10
+ ### Features
11
+
12
+ - ✅ Active Governance: Real-time policy enforcement during AI tests
13
+ - ✅ VAP Receipts: Cryptographic evidence for compliance audits
14
+ - ✅ AI-BOM Verification: Ensure model integrity and provenance
15
+ - ✅ Trust Tokens: JIT authentication for each test run
16
+ - ✅ Predictive Enforcement: ML-based risk prediction
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install verilink-aiverify-plugin
22
+ ```
23
+
24
+ ## Configuration
25
+ Set environment variables:
26
+
27
+ ```bash
28
+ export VERILINK_API_URL=https://api.verilink.os
29
+ export VERILINK_API_KEY=your_api_key
30
+ export VERILINK_AGENT_ID=your_agent_id
31
+ export VERILINK_ORG_ID=your_org_id
32
+ ```
33
+
34
+ ## Quick Start
35
+ ```python
36
+ import asyncio
37
+ from verilink_plugin import VeriLinkGovernancePlugin
38
+
39
+ async def test_model():
40
+ plugin = VeriLinkGovernancePlugin()
41
+
42
+ result = await plugin.run_test(
43
+ {"model_id": "model-001", "dataset": "test-data"},
44
+ lambda config: {"passed": True, "artifacts": {}}
45
+ )
46
+
47
+ print(f"Passed: {result.passed}")
48
+ print(f"Receipt: {result.receipt_id}")
49
+
50
+ await plugin.cleanup()
51
+
52
+ asyncio.run(test_model())
53
+ ```
54
+
55
+ ## License
56
+ Apache 2.0
@@ -0,0 +1,21 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "verilink-aiverify-plugin"
7
+ version = "1.0.0"
8
+ description = "VeriLinkOS Active Governance Integration for AI Verify"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "Apache-2.0"}
12
+ dependencies = [
13
+ "httpx>=0.23.0,<0.28.0",
14
+ "pydantic>=1.10.0,<3.0.0",
15
+ "python-dotenv>=0.19.0,<2.1.0",
16
+ "tenacity>=8.0.0,<9.1.0",
17
+ ]
18
+
19
+ [tool.ruff]
20
+ line-length = 100
21
+ target-version = "py39"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,20 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="verilink-aiverify-plugin",
5
+ version="1.0.0",
6
+ description="VeriLinkOS Active Governance Integration for AI Verify",
7
+ packages=find_packages(),
8
+ install_requires=[
9
+ "httpx>=0.23.0,<0.28.0",
10
+ "pydantic>=1.10.0,<3.0.0",
11
+ "python-dotenv>=0.19.0,<2.1.0",
12
+ "tenacity>=8.0.0,<9.1.0",
13
+ ],
14
+ entry_points={
15
+ "aiverify.plugins": [
16
+ "verilink_os = verilink_plugin.plugin:VeriLinkGovernancePlugin",
17
+ ],
18
+ },
19
+ python_requires=">=3.9",
20
+ )
@@ -0,0 +1,11 @@
1
+ import pytest
2
+ from verilink_plugin import VeriLinkGovernancePlugin
3
+
4
+ @pytest.mark.asyncio
5
+ async def test_plugin_metadata(mock_config):
6
+ plugin = VeriLinkGovernancePlugin(mock_config)
7
+ metadata = plugin.get_metadata()
8
+
9
+ assert metadata["name"] == "VeriLinkOS Governance Plugin"
10
+ assert metadata["version"] == "1.0.0"
11
+ assert metadata["entry_point"] == "verilink_os"
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.4
2
+ Name: verilink-aiverify-plugin
3
+ Version: 1.0.0
4
+ Summary: VeriLinkOS Active Governance Integration for AI Verify
5
+ License: Apache-2.0
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: httpx<0.28.0,>=0.23.0
10
+ Requires-Dist: pydantic<3.0.0,>=1.10.0
11
+ Requires-Dist: python-dotenv<2.1.0,>=0.19.0
12
+ Requires-Dist: tenacity<9.1.0,>=8.0.0
13
+ Dynamic: license-file
14
+ Dynamic: requires-python
15
+
16
+ # VeriLinkOS AI Verify Plugin
17
+
18
+ [![PyPI version](https://badge.fury.io/py/verilink-aiverify-plugin.svg)](https://badge.fury.io/py/verilink-aiverify-plugin)
19
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
20
+
21
+ ## Overview
22
+
23
+ VeriLinkOS AI Verify Plugin integrates active governance capabilities from VeriLinkOS into the AI Verify testing framework.
24
+
25
+ ### Features
26
+
27
+ - ✅ Active Governance: Real-time policy enforcement during AI tests
28
+ - ✅ VAP Receipts: Cryptographic evidence for compliance audits
29
+ - ✅ AI-BOM Verification: Ensure model integrity and provenance
30
+ - ✅ Trust Tokens: JIT authentication for each test run
31
+ - ✅ Predictive Enforcement: ML-based risk prediction
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pip install verilink-aiverify-plugin
37
+ ```
38
+
39
+ ## Configuration
40
+ Set environment variables:
41
+
42
+ ```bash
43
+ export VERILINK_API_URL=https://api.verilink.os
44
+ export VERILINK_API_KEY=your_api_key
45
+ export VERILINK_AGENT_ID=your_agent_id
46
+ export VERILINK_ORG_ID=your_org_id
47
+ ```
48
+
49
+ ## Quick Start
50
+ ```python
51
+ import asyncio
52
+ from verilink_plugin import VeriLinkGovernancePlugin
53
+
54
+ async def test_model():
55
+ plugin = VeriLinkGovernancePlugin()
56
+
57
+ result = await plugin.run_test(
58
+ {"model_id": "model-001", "dataset": "test-data"},
59
+ lambda config: {"passed": True, "artifacts": {}}
60
+ )
61
+
62
+ print(f"Passed: {result.passed}")
63
+ print(f"Receipt: {result.receipt_id}")
64
+
65
+ await plugin.cleanup()
66
+
67
+ asyncio.run(test_model())
68
+ ```
69
+
70
+ ## License
71
+ Apache 2.0
@@ -0,0 +1,17 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ tests/test_plugin.py
6
+ verilink_aiverify_plugin.egg-info/PKG-INFO
7
+ verilink_aiverify_plugin.egg-info/SOURCES.txt
8
+ verilink_aiverify_plugin.egg-info/dependency_links.txt
9
+ verilink_aiverify_plugin.egg-info/entry_points.txt
10
+ verilink_aiverify_plugin.egg-info/requires.txt
11
+ verilink_aiverify_plugin.egg-info/top_level.txt
12
+ verilink_plugin/__init__.py
13
+ verilink_plugin/client.py
14
+ verilink_plugin/exceptions.py
15
+ verilink_plugin/models.py
16
+ verilink_plugin/plugin.py
17
+ verilink_plugin/utils.py
@@ -0,0 +1,2 @@
1
+ [aiverify.plugins]
2
+ verilink_os = verilink_plugin.plugin:VeriLinkGovernancePlugin
@@ -0,0 +1,4 @@
1
+ httpx<0.28.0,>=0.23.0
2
+ pydantic<3.0.0,>=1.10.0
3
+ python-dotenv<2.1.0,>=0.19.0
4
+ tenacity<9.1.0,>=8.0.0
@@ -0,0 +1,18 @@
1
+ """
2
+ VeriLinkOS AI Verify Plugin
3
+ """
4
+ from .plugin import VeriLinkGovernancePlugin
5
+ from .client import VeriLinkClient
6
+ from .models import VeriLinkConfig, VeriLinkTestResult, VeriLinkEnforcementMode
7
+ from .exceptions import VeriLinkError
8
+
9
+ __version__ = "1.0.0"
10
+
11
+ __all__ = [
12
+ "VeriLinkGovernancePlugin",
13
+ "VeriLinkClient",
14
+ "VeriLinkConfig",
15
+ "VeriLinkTestResult",
16
+ "VeriLinkEnforcementMode",
17
+ "VeriLinkError"
18
+ ]
@@ -0,0 +1,102 @@
1
+ """
2
+ HTTP client for VeriLinkOS API
3
+ """
4
+
5
+ import logging
6
+ import time
7
+ from typing import Dict, Any, Optional
8
+ import httpx
9
+ from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
10
+
11
+ from .models import VeriLinkConfig
12
+ from .exceptions import (
13
+ VeriLinkConnectionError,
14
+ VeriLinkAuthError,
15
+ VeriLinkTimeoutError
16
+ )
17
+
18
+ logger = logging.getLogger("verilink_plugin")
19
+
20
+ class VeriLinkClient:
21
+ """Core API client for VeriLinkOS"""
22
+
23
+ def __init__(self, config: VeriLinkConfig):
24
+ self.config = config
25
+ self.headers = {
26
+ "X-VeriLink-API-Key": config.api_key,
27
+ "X-VeriLink-Agent-ID": config.agent_id,
28
+ "Content-Type": "application/json",
29
+ "User-Agent": "VeriLink-AIVerify-Plugin/1.0.0"
30
+ }
31
+ self.client = httpx.AsyncClient(
32
+ base_url=config.api_url,
33
+ headers=self.headers,
34
+ timeout=config.timeout
35
+ )
36
+
37
+ async def verilink_health_check(self) -> bool:
38
+ """Check if VeriLinkOS API is healthy"""
39
+ try:
40
+ response = await self.client.get("/health")
41
+ return response.status_code == 200
42
+ except Exception as e:
43
+ logger.error(f"VeriLink health check failed: {str(e)}")
44
+ return False
45
+
46
+ @retry(
47
+ stop=stop_after_attempt(3),
48
+ wait=wait_exponential(multiplier=1, min=2, max=10),
49
+ retry=retry_if_exception_type((httpx.RequestError, VeriLinkTimeoutError))
50
+ )
51
+ async def _verilink_request(self, method: str, endpoint: str, data: Optional[Dict] = None) -> Dict:
52
+ """Make a request to VeriLinkOS API with retry logic"""
53
+ try:
54
+ response = await self.client.request(method, endpoint, json=data)
55
+
56
+ if response.status_code == 401:
57
+ raise VeriLinkAuthError("Invalid VeriLink API credentials")
58
+
59
+ response.raise_for_status()
60
+ return response.json()
61
+
62
+ except httpx.TimeoutException:
63
+ raise VeriLinkTimeoutError(f"Request to {endpoint} timed out")
64
+ except httpx.HTTPStatusError as e:
65
+ raise VeriLinkConnectionError(f"API Error {e.response.status_code}: {e.response.text}")
66
+ except Exception as e:
67
+ raise VeriLinkConnectionError(f"Unexpected connection error: {str(e)}")
68
+
69
+ async def verilink_get_token(self) -> str:
70
+ """Retrieve a short-lived JIT Trust Token"""
71
+ res = await self._verilink_request("POST", "/v1/auth/token", {
72
+ "org_id": self.config.organization_id,
73
+ "agent_id": self.config.agent_id
74
+ })
75
+ return res["trust_token"]
76
+
77
+ async def verilink_verify_aibom(self, aibom_data: Dict) -> Dict:
78
+ """Validate Model Integrity via AI-BOM verification"""
79
+ return await self._verilink_request("POST", "/v1/governance/verify-aibom", aibom_data)
80
+
81
+ async def verilink_generate_receipt(self, test_evidence: Dict) -> Dict:
82
+ """Generate a VAP Receipt"""
83
+ return await self._verilink_request("POST", "/v1/governance/receipt", {
84
+ "evidence": test_evidence,
85
+ "timestamp": time.time(),
86
+ "batch": True
87
+ })
88
+
89
+ async def verilink_verify_receipt(self, receipt_id: str) -> Dict:
90
+ """Verify an existing receipt"""
91
+ return await self._verilink_request("GET", f"/v1/governance/receipt/{receipt_id}/verify")
92
+
93
+ async def verilink_predict_outcome(self, config_fingerprint: str) -> float:
94
+ """Predict failure probability"""
95
+ res = await self._verilink_request("POST", "/v1/analytics/predict", {
96
+ "fingerprint": config_fingerprint
97
+ })
98
+ return res.get("failure_probability", 0.0)
99
+
100
+ async def close(self):
101
+ """Close the HTTP client"""
102
+ await self.client.aclose()
@@ -0,0 +1,27 @@
1
+ """
2
+ Custom exceptions for VeriLinkOS plugin
3
+ """
4
+
5
+ class VeriLinkError(Exception):
6
+ """Base exception for all VeriLink plugin errors."""
7
+ pass
8
+
9
+ class VeriLinkConnectionError(VeriLinkError):
10
+ """Raised when the plugin cannot connect to VeriLinkOS API."""
11
+ pass
12
+
13
+ class VeriLinkAuthError(VeriLinkError):
14
+ """Raised on authentication failures."""
15
+ pass
16
+
17
+ class VeriLinkValidationError(VeriLinkError):
18
+ """Raised when configuration or payload validation fails."""
19
+ pass
20
+
21
+ class VeriLinkTimeoutError(VeriLinkError):
22
+ """Raised when a VeriLinkOS operation times out."""
23
+ pass
24
+
25
+ class VeriLinkConfigError(VeriLinkError):
26
+ """Raised when configuration is invalid."""
27
+ pass
@@ -0,0 +1,63 @@
1
+ """
2
+ Data models for VeriLinkOS plugin
3
+ """
4
+
5
+ from typing import Dict, Any, Optional
6
+ from pydantic import BaseModel, Field, validator
7
+ from enum import Enum
8
+ import uuid
9
+
10
+ class VeriLinkEnforcementMode(str, Enum):
11
+ """Enforcement modes for governance"""
12
+ BLOCK = "block"
13
+ WARN = "warn"
14
+ LOG = "log"
15
+ OBSERVE = "observe"
16
+
17
+ class VeriLinkConfig(BaseModel):
18
+ """Configuration for VeriLinkOS plugin"""
19
+ api_url: str = Field(..., description="VeriLinkOS API URL")
20
+ api_key: str = Field(..., description="VeriLinkOS API key")
21
+ agent_id: str = Field(..., description="Agent identifier")
22
+ organization_id: str = Field(..., description="Organization identifier")
23
+ enforce_mode: VeriLinkEnforcementMode = Field(
24
+ default=VeriLinkEnforcementMode.BLOCK,
25
+ description="Enforcement mode"
26
+ )
27
+ timeout: int = Field(default=30, description="Request timeout in seconds")
28
+ max_retries: int = Field(default=3, description="Maximum retry attempts")
29
+ use_cache: bool = Field(default=True, description="Enable caching")
30
+ cache_ttl: int = Field(default=300, description="Cache TTL in seconds")
31
+ predictive_enabled: bool = Field(default=True, description="Enable predictive enforcement")
32
+ jurisdiction: str = Field(default="SG", description="Legal jurisdiction")
33
+
34
+ @validator("api_url")
35
+ def validate_url(cls, v):
36
+ if not v.startswith(("http://", "https://")):
37
+ raise ValueError("VERILINK_API_URL must start with http:// or https://")
38
+ return v
39
+
40
+ class VeriLinkTestResult(BaseModel):
41
+ """Result of a test with VeriLinkOS governance"""
42
+ passed: bool
43
+ error: Optional[str] = None
44
+ details: Dict[str, Any] = Field(default_factory=dict)
45
+ artifacts: Dict[str, Any] = Field(default_factory=dict)
46
+ receipt_id: Optional[str] = None
47
+ verification_url: Optional[str] = None
48
+ merkle_root: Optional[str] = None
49
+ prediction_score: Optional[float] = None
50
+ governance_status: str = "evaluated"
51
+
52
+ def to_dict(self) -> Dict[str, Any]:
53
+ return self.dict(exclude_none=True)
54
+
55
+ class VeriLinkReceipt(BaseModel):
56
+ """VAP Receipt model"""
57
+ receipt_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
58
+ test_id: str
59
+ timestamp: float
60
+ signature: str
61
+ evidence_hash: str
62
+ merkle_root: Optional[str] = None
63
+ verification_url: Optional[str] = None
@@ -0,0 +1,181 @@
1
+ """
2
+ Main VeriLinkOS Governance Plugin for AI Verify
3
+ """
4
+
5
+ import logging
6
+ import asyncio
7
+ import hashlib
8
+ import json
9
+ from typing import Dict, Any, Optional, Callable
10
+
11
+ from .models import VeriLinkConfig, VeriLinkTestResult, VeriLinkEnforcementMode
12
+ from .client import VeriLinkClient
13
+ from .exceptions import VeriLinkAuthError
14
+
15
+ logger = logging.getLogger("verilink_plugin")
16
+
17
+ class VeriLinkGovernancePlugin:
18
+ """Main integration plugin for AI Verify"""
19
+
20
+ PLUGIN_ID = "verilink_os_governance"
21
+ PLUGIN_VERSION = "1.0.0"
22
+
23
+ def __init__(self, config_dict: Optional[Dict] = None):
24
+ self.config = VeriLinkConfig(**(config_dict or {}))
25
+ self.client = VeriLinkClient(self.config)
26
+ self._aibom_cache: Dict[str, Any] = {}
27
+ self._initialized = False
28
+
29
+ async def verilink_setup(self):
30
+ """Initialize the plugin and check connectivity"""
31
+ try:
32
+ if await self.client.verilink_health_check():
33
+ self._initialized = True
34
+ logger.info("VeriLinkOS connection established")
35
+ else:
36
+ logger.warning("VeriLinkOS API unreachable. Operating in fail-safe mode.")
37
+ self._initialized = False
38
+ except Exception as e:
39
+ logger.error(f"VeriLink setup failed: {str(e)}")
40
+ self._initialized = False
41
+
42
+ async def run_test(self, test_config: Dict[str, Any], test_func: Callable) -> VeriLinkTestResult:
43
+ """Run an AI test with VeriLinkOS governance"""
44
+ try:
45
+ if not self._initialized:
46
+ await self.verilink_setup()
47
+
48
+ # 1. Predictive enforcement
49
+ if self.config.predictive_enabled:
50
+ prediction = await self._verilink_predict_risk(test_config)
51
+ if prediction > 0.8 and self.config.enforce_mode == VeriLinkEnforcementMode.BLOCK:
52
+ return VeriLinkTestResult(
53
+ passed=False,
54
+ error="Predictive block: high risk detected",
55
+ prediction_score=prediction,
56
+ governance_status="blocked"
57
+ )
58
+
59
+ # 2. Get trust token
60
+ try:
61
+ await self.client.verilink_get_token()
62
+ logger.info("VeriLink trust token acquired")
63
+ except Exception as e:
64
+ if self.config.enforce_mode == VeriLinkEnforcementMode.BLOCK:
65
+ return VeriLinkTestResult(
66
+ passed=False,
67
+ error=f"Authentication failed: {str(e)}",
68
+ governance_status="blocked"
69
+ )
70
+ return self._fail_open_result(str(e))
71
+
72
+ # 3. Verify AI-BOM
73
+ try:
74
+ aibom_status = await self._verilink_check_aibom(test_config)
75
+ if not aibom_status.get("valid") and self.config.enforce_mode == VeriLinkEnforcementMode.BLOCK:
76
+ return VeriLinkTestResult(
77
+ passed=False,
78
+ error="AI-BOM Verification Failed: Model not registered or tampered",
79
+ governance_status="blocked"
80
+ )
81
+ except Exception as e:
82
+ if self.config.enforce_mode == VeriLinkEnforcementMode.BLOCK:
83
+ return VeriLinkTestResult(
84
+ passed=False,
85
+ error=f"AI-BOM verification error: {str(e)}",
86
+ governance_status="blocked"
87
+ )
88
+ logger.warning(f"AI-BOM verification degraded: {e}")
89
+
90
+ # 4. Run the actual test
91
+ test_start_time = asyncio.get_event_loop().time()
92
+ test_raw_result = await test_func(test_config)
93
+ test_duration = asyncio.get_event_loop().time() - test_start_time
94
+
95
+ # 5. Generate VAP receipt
96
+ evidence = {
97
+ "test_config": test_config,
98
+ "raw_result": test_raw_result,
99
+ "duration": test_duration,
100
+ "timestamp": asyncio.get_event_loop().time()
101
+ }
102
+ receipt_data = await self.client.verilink_generate_receipt(evidence)
103
+
104
+ # 6. Verify the receipt
105
+ verification = await self.client.verilink_verify_receipt(receipt_data["receipt_id"])
106
+ is_verified = verification.get("verified", False)
107
+
108
+ return VeriLinkTestResult(
109
+ passed=test_raw_result.get("passed", False),
110
+ receipt_id=receipt_data["receipt_id"],
111
+ verification_url=f"{self.config.api_url}/verify/{receipt_data['receipt_id']}",
112
+ merkle_root=receipt_data.get("merkle_root"),
113
+ details={
114
+ "receipt_verified": is_verified,
115
+ "duration": test_duration,
116
+ "governance_mode": self.config.enforce_mode.value
117
+ },
118
+ artifacts=test_raw_result.get("artifacts", {}),
119
+ governance_status="approved" if is_verified else "pending"
120
+ )
121
+
122
+ except VeriLinkAuthError as e:
123
+ if self.config.enforce_mode == VeriLinkEnforcementMode.BLOCK:
124
+ raise
125
+ return self._fail_open_result(str(e))
126
+
127
+ except Exception as e:
128
+ logger.error(f"VeriLink plugin error: {e}", exc_info=True)
129
+ if self.config.enforce_mode == VeriLinkEnforcementMode.BLOCK:
130
+ return VeriLinkTestResult(
131
+ passed=False,
132
+ error=str(e),
133
+ governance_status="blocked"
134
+ )
135
+ return self._fail_open_result(str(e))
136
+
137
+ async def _verilink_check_aibom(self, test_config: Dict) -> Dict:
138
+ """Check AI-BOM with caching"""
139
+ model_id = test_config.get("model_id", "default")
140
+
141
+ if self.config.use_cache and model_id in self._aibom_cache:
142
+ logger.debug(f"AI-BOM cache hit for {model_id}")
143
+ return self._aibom_cache[model_id]
144
+
145
+ res = await self.client.verilink_verify_aibom({"model_id": model_id})
146
+
147
+ if self.config.use_cache:
148
+ self._aibom_cache[model_id] = res
149
+
150
+ return res
151
+
152
+ async def _verilink_predict_risk(self, test_config: Dict) -> float:
153
+ """Predict failure probability"""
154
+ fingerprint = hashlib.sha256(
155
+ json.dumps(test_config, sort_keys=True).encode()
156
+ ).hexdigest()
157
+
158
+ return await self.client.verilink_predict_outcome(fingerprint)
159
+
160
+ def _fail_open_result(self, error_msg: str) -> VeriLinkTestResult:
161
+ """Return fail-open result (pass with warning)"""
162
+ logger.warning(f"VeriLink fail-open: {error_msg}")
163
+ return VeriLinkTestResult(
164
+ passed=True,
165
+ error=error_msg,
166
+ governance_status="degraded",
167
+ details={"mode": "fail_open"}
168
+ )
169
+
170
+ def get_metadata(self) -> Dict[str, str]:
171
+ """Return plugin metadata for AI Verify"""
172
+ return {
173
+ "name": "VeriLinkOS Governance Plugin",
174
+ "version": self.PLUGIN_VERSION,
175
+ "entry_point": "verilink_os",
176
+ "description": "Active governance integration for AI Verify"
177
+ }
178
+
179
+ async def cleanup(self):
180
+ """Clean up resources"""
181
+ await self.client.close()
@@ -0,0 +1,31 @@
1
+ """
2
+ Utility functions for VeriLinkOS plugin
3
+ """
4
+
5
+ import logging
6
+ import hashlib
7
+ import json
8
+ from typing import Dict, Any
9
+
10
+ def verilink_setup_logger(name: str = "verilink_plugin") -> logging.Logger:
11
+ """Setup and return a logger for the plugin"""
12
+ logger = logging.getLogger(name)
13
+ if not logger.handlers:
14
+ handler = logging.StreamHandler()
15
+ formatter = logging.Formatter(
16
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
17
+ )
18
+ handler.setFormatter(formatter)
19
+ logger.addHandler(handler)
20
+ return logger
21
+
22
+ def verilink_calculate_evidence_hash(data: Dict[str, Any]) -> str:
23
+ """Computes a deterministic SHA256 hash of the evidence data."""
24
+ encoded = json.dumps(data, sort_keys=True).encode()
25
+ return hashlib.sha256(encoded).hexdigest()
26
+
27
+ def verilink_validate_config(url: str, key: str) -> bool:
28
+ """Basic validation for VeriLink API connectivity parameters."""
29
+ if not url.startswith(("http://", "https://")):
30
+ return False
31
+ return len(key) > 8