swiftapi-python 1.2.2__py3-none-any.whl → 1.3.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.
- swiftapi/__init__.py +75 -96
- swiftapi/__main__.py +2 -0
- swiftapi/anthropic.py +236 -222
- swiftapi/brake/__init__.py +45 -0
- swiftapi/brake/benchmarks.py +111 -0
- swiftapi/brake/broker.py +274 -0
- swiftapi/brake/core.py +420 -0
- swiftapi/brake/install.py +268 -0
- swiftapi/brake/mcp.py +160 -0
- swiftapi/brake/observations.py +61 -0
- swiftapi/brake/qualification.py +116 -0
- swiftapi/brake/remote.py +90 -0
- swiftapi/cli.py +150 -0
- swiftapi/client.py +328 -309
- swiftapi/enforcement.py +281 -280
- swiftapi/openai.py +243 -225
- swiftapi/py.typed +0 -0
- swiftapi/verifier.py +182 -130
- swiftapi_python-1.3.0.dist-info/METADATA +147 -0
- swiftapi_python-1.3.0.dist-info/RECORD +26 -0
- {swiftapi_python-1.2.2.dist-info → swiftapi_python-1.3.0.dist-info}/WHEEL +1 -1
- swiftapi_python-1.3.0.dist-info/entry_points.txt +2 -0
- swiftapi_python-1.2.2.dist-info/METADATA +0 -255
- swiftapi_python-1.2.2.dist-info/RECORD +0 -13
- {swiftapi_python-1.2.2.dist-info → swiftapi_python-1.3.0.dist-info}/licenses/LICENSE +0 -0
- {swiftapi_python-1.2.2.dist-info → swiftapi_python-1.3.0.dist-info}/top_level.txt +0 -0
swiftapi/verifier.py
CHANGED
|
@@ -1,130 +1,182 @@
|
|
|
1
|
-
"""
|
|
2
|
-
SwiftAPI SDK - Ed25519 Signature Verifier (The Shield)
|
|
3
|
-
|
|
4
|
-
This module provides OFFLINE cryptographic verification of execution attestations.
|
|
5
|
-
It does not require network connectivity - it uses the hardcoded SwiftAPI public key.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import base64
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
from
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
from nacl.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if not
|
|
55
|
-
raise SignatureVerificationError("
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
"""
|
|
127
|
-
try:
|
|
128
|
-
return
|
|
129
|
-
except
|
|
130
|
-
|
|
1
|
+
"""
|
|
2
|
+
SwiftAPI SDK - Ed25519 Signature Verifier (The Shield)
|
|
3
|
+
|
|
4
|
+
This module provides OFFLINE cryptographic verification of execution attestations.
|
|
5
|
+
It does not require network connectivity - it uses the hardcoded SwiftAPI public key.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import base64
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
from datetime import datetime, timezone
|
|
12
|
+
from typing import Dict, Any
|
|
13
|
+
|
|
14
|
+
from nacl.signing import VerifyKey
|
|
15
|
+
from nacl.exceptions import BadSignatureError
|
|
16
|
+
|
|
17
|
+
from .exceptions import (
|
|
18
|
+
SignatureVerificationError,
|
|
19
|
+
AttestationExpiredError,
|
|
20
|
+
SwiftAPIError,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# SwiftAPI's Ed25519 Public Key (Base64)
|
|
24
|
+
# This is the ONLY source of truth for attestation verification
|
|
25
|
+
SWIFTAPI_PUBLIC_KEY_B64 = "jajZXZ0R3CUWkE5/5Mxx5Y76CdsSzaPDuT7aWnooZSk="
|
|
26
|
+
|
|
27
|
+
# Decode public key once at module load
|
|
28
|
+
SWIFTAPI_PUBLIC_KEY = base64.b64decode(SWIFTAPI_PUBLIC_KEY_B64)
|
|
29
|
+
VERIFY_KEY = VerifyKey(SWIFTAPI_PUBLIC_KEY)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def verify_signature(attestation: Dict[str, Any], ignore_expiry: bool = False) -> bool:
|
|
33
|
+
"""
|
|
34
|
+
Verify the Ed25519 signature of an execution attestation.
|
|
35
|
+
|
|
36
|
+
This is OFFLINE verification - no network required.
|
|
37
|
+
The signature proves the attestation was issued by SwiftAPI.
|
|
38
|
+
|
|
39
|
+
Signature authenticity is permanent. Expiry is about the execution window,
|
|
40
|
+
not whether the attestation is genuine. Use ignore_expiry=True for audit
|
|
41
|
+
and post-hoc verification.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
attestation: The execution_attestation dict from /verify response
|
|
45
|
+
ignore_expiry: If True, verify signature without checking expiry
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
True if signature is valid
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
SignatureVerificationError: If signature is invalid or missing
|
|
52
|
+
AttestationExpiredError: If attestation has expired (and ignore_expiry is False)
|
|
53
|
+
"""
|
|
54
|
+
if not isinstance(attestation, dict):
|
|
55
|
+
raise SignatureVerificationError("Attestation must be a JSON object")
|
|
56
|
+
|
|
57
|
+
# Extract required fields
|
|
58
|
+
signature_b64 = attestation.get("signature")
|
|
59
|
+
if not signature_b64:
|
|
60
|
+
raise SignatureVerificationError("Missing signature in attestation")
|
|
61
|
+
|
|
62
|
+
jti = attestation.get("jti")
|
|
63
|
+
action_fingerprint = attestation.get("action_fingerprint")
|
|
64
|
+
expires_at = attestation.get("expires_at")
|
|
65
|
+
|
|
66
|
+
if not all(isinstance(value, str) and value for value in (jti, action_fingerprint, expires_at)):
|
|
67
|
+
raise SignatureVerificationError("Incomplete attestation: missing required fields")
|
|
68
|
+
|
|
69
|
+
# Verify signature FIRST — authenticity is permanent
|
|
70
|
+
try:
|
|
71
|
+
signed_payload = _reconstruct_signed_payload(attestation)
|
|
72
|
+
except (TypeError, ValueError):
|
|
73
|
+
raise SignatureVerificationError("Attestation contains invalid JSON fields")
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
signature = base64.b64decode(signature_b64, validate=True)
|
|
77
|
+
except Exception as e:
|
|
78
|
+
raise SignatureVerificationError(f"Invalid signature encoding: {e}")
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
VERIFY_KEY.verify(signed_payload, signature)
|
|
82
|
+
except (BadSignatureError, ValueError, TypeError):
|
|
83
|
+
raise SignatureVerificationError(
|
|
84
|
+
"INVALID SIGNATURE: Attestation was not signed by SwiftAPI. "
|
|
85
|
+
"This could indicate a forged or tampered attestation."
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Check expiration AFTER signature (execution window, not authenticity)
|
|
89
|
+
if not ignore_expiry:
|
|
90
|
+
try:
|
|
91
|
+
expiry = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
|
|
92
|
+
if expiry.tzinfo is None:
|
|
93
|
+
raise ValueError("Expiration must include a timezone")
|
|
94
|
+
now = datetime.now(timezone.utc)
|
|
95
|
+
if now >= expiry:
|
|
96
|
+
raise AttestationExpiredError(f"Attestation expired at {expires_at}")
|
|
97
|
+
except ValueError as e:
|
|
98
|
+
raise SignatureVerificationError(f"Invalid expiration format: {e}")
|
|
99
|
+
|
|
100
|
+
return True
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _reconstruct_signed_payload(attestation: Dict[str, Any]) -> bytes:
|
|
104
|
+
"""
|
|
105
|
+
Reconstruct the exact payload that was signed by SwiftAPI.
|
|
106
|
+
|
|
107
|
+
The server signs the attestation BEFORE adding signature/signing_mode fields.
|
|
108
|
+
We must reconstruct that exact payload.
|
|
109
|
+
"""
|
|
110
|
+
# Copy attestation and remove fields that weren't in the signed payload.
|
|
111
|
+
# signature/signing_mode are added after signing.
|
|
112
|
+
# /attest appends action_data and policy diagnostics after signing.
|
|
113
|
+
# They are never used as authorization evidence.
|
|
114
|
+
_unsigned = (
|
|
115
|
+
"signature", "signing_mode", "action_data", "denial_reason",
|
|
116
|
+
"violated_policies", "evaluated_policies", "evaluation_context",
|
|
117
|
+
)
|
|
118
|
+
signed_fields = {k: v for k, v in attestation.items() if k not in _unsigned}
|
|
119
|
+
|
|
120
|
+
# Deterministic JSON serialization (must match server exactly)
|
|
121
|
+
payload_str = json.dumps(signed_fields, sort_keys=True, separators=(",", ":"))
|
|
122
|
+
return payload_str.encode("utf-8")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _snapshot_action_data(data: Dict[str, Any]) -> Dict[str, Any]:
|
|
126
|
+
"""Detach request data and normalize it exactly as JSON transport does."""
|
|
127
|
+
try:
|
|
128
|
+
return json.loads(json.dumps(data, allow_nan=False))
|
|
129
|
+
except (TypeError, ValueError):
|
|
130
|
+
raise SwiftAPIError("Action data must contain JSON-serializable values")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _action_fingerprint(data: Dict[str, Any], truncated: bool = False) -> str:
|
|
134
|
+
"""Match the backend's canonical JSON hash (/attest uses 32 hex chars)."""
|
|
135
|
+
canonical = json.dumps(data, sort_keys=True, separators=(",", ":"))
|
|
136
|
+
fingerprint = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
|
|
137
|
+
return fingerprint[:32] if truncated else fingerprint
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _validate_action_binding(
|
|
141
|
+
attestation: Dict[str, Any], action_type: str, action_fingerprint: str
|
|
142
|
+
) -> bool:
|
|
143
|
+
"""Check signed execution fields after verify_signature has succeeded."""
|
|
144
|
+
if attestation.get("action_type") != action_type:
|
|
145
|
+
raise SignatureVerificationError("Attestation action type does not match the request")
|
|
146
|
+
if attestation.get("action_fingerprint") != action_fingerprint:
|
|
147
|
+
raise SignatureVerificationError("Attestation action fingerprint does not match the request")
|
|
148
|
+
approved = attestation.get("approved")
|
|
149
|
+
if type(approved) is not bool:
|
|
150
|
+
raise SignatureVerificationError("Attestation approval must be a boolean")
|
|
151
|
+
return approved
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def get_public_key() -> str:
|
|
155
|
+
"""Return SwiftAPI's public key in Base64 format."""
|
|
156
|
+
return SWIFTAPI_PUBLIC_KEY_B64
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def is_valid(attestation: Dict[str, Any], ignore_expiry: bool = False) -> bool:
|
|
160
|
+
"""
|
|
161
|
+
Check if attestation is valid without raising exceptions.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
attestation: The execution_attestation dict
|
|
165
|
+
ignore_expiry: If True, only check signature authenticity
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
True if valid, False otherwise
|
|
169
|
+
"""
|
|
170
|
+
try:
|
|
171
|
+
return verify_signature(attestation, ignore_expiry=ignore_expiry)
|
|
172
|
+
except Exception:
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def claim_attestation(attestation: Dict[str, Any]) -> None:
|
|
177
|
+
"""One-use local replay claim; call only after signature and action verification."""
|
|
178
|
+
import os
|
|
179
|
+
from pathlib import Path
|
|
180
|
+
from .brake.core import ReplayLedger
|
|
181
|
+
root = Path(os.environ.get("SWIFTAPI_HOME", Path.home() / ".local/share/swiftapi"))
|
|
182
|
+
ReplayLedger(root).claim(SWIFTAPI_PUBLIC_KEY_B64, attestation["jti"])
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: swiftapi-python
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: SwiftAPI Python SDK - AI Action Verification Gateway
|
|
5
|
+
Author-email: Rayan Pal <rayan@swiftapi.ai>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://swiftapi.ai
|
|
8
|
+
Project-URL: Documentation, https://getswiftapi.com/docs
|
|
9
|
+
Keywords: swiftapi,ai,verification,attestation,security,governance,enforcement
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: requests<3,>=2.32.3
|
|
25
|
+
Requires-Dist: pynacl<2,>=1.5.0
|
|
26
|
+
Requires-Dist: colorama<1,>=0.4.6
|
|
27
|
+
Requires-Dist: tomli<3,>=2; python_version < "3.11"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: hypothesis<7,>=6; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: types-requests<3,>=2.32.3; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# SwiftAPI Python SDK
|
|
38
|
+
|
|
39
|
+
A prerequisite before a protected action. Local Swift Brake verifies explicit
|
|
40
|
+
permission, executes its registered capability once, and creates signed receipts.
|
|
41
|
+
Codex or Claude Code remains the coding agent. No second model is involved.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install swiftapi-python
|
|
45
|
+
swiftapi doctor
|
|
46
|
+
swiftapi brake test
|
|
47
|
+
swiftapi brake install --dry-run
|
|
48
|
+
swiftapi brake install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Python 3.9+, macOS and Linux. The local test needs no account, API key, model,
|
|
52
|
+
or cloud service. Restart the coding agent after installing the MCP integration.
|
|
53
|
+
|
|
54
|
+
## Try the brake
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
swiftapi brake propose hello.txt "Hello from Swift Brake"
|
|
58
|
+
# Copy the returned request_id into the following commands.
|
|
59
|
+
swiftapi brake execute REQUEST_ID
|
|
60
|
+
# GATE_BLOCK: no marker is written.
|
|
61
|
+
swiftapi brake authorize REQUEST_ID
|
|
62
|
+
swiftapi brake execute REQUEST_ID
|
|
63
|
+
# AUTHORIZED_EXECUTION: exact marker bytes are written once.
|
|
64
|
+
swiftapi brake execute REQUEST_ID
|
|
65
|
+
# GATE_BLOCK: the authorization cannot execute again.
|
|
66
|
+
swiftapi status
|
|
67
|
+
swiftapi receipts
|
|
68
|
+
swiftapi verify RECEIPT_PATH --public-key PUBLIC_KEY_PATH
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`status` prints the sandbox and public-key path. `execute` returns the receipt
|
|
72
|
+
path. The operator authorizes in a separate terminal; authorization is deliberately
|
|
73
|
+
absent from the MCP tool surface. A signature requires an independently trusted
|
|
74
|
+
verification key, never a key blindly accepted from the receipt itself.
|
|
75
|
+
|
|
76
|
+
`swiftapi brake` presents `swiftapi>` and delegates ordinary input to the existing
|
|
77
|
+
Codex CLI. `swiftapi brake --agent claude` uses Claude Code. These host calls use
|
|
78
|
+
your existing account; the local test itself makes no model calls.
|
|
79
|
+
|
|
80
|
+
## Python
|
|
81
|
+
|
|
82
|
+
The old imports remain available: `from swiftapi import SwiftAPI, Enforcement`.
|
|
83
|
+
The new local API does not require a remote account:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from pathlib import Path
|
|
87
|
+
from tempfile import mkdtemp
|
|
88
|
+
from swiftapi import ActionEnvelope, BindingCondition, LocalAuthority, LocalGuard
|
|
89
|
+
|
|
90
|
+
action = ActionEnvelope("example.append", {"value": "verified"}, "Append one value")
|
|
91
|
+
state = {"operator_approved": True} # Supplied by trusted application code.
|
|
92
|
+
condition = BindingCondition(action.action_hash, state)
|
|
93
|
+
guard = LocalGuard(LocalAuthority(), Path(mkdtemp()) / "ledger")
|
|
94
|
+
values = []
|
|
95
|
+
guard.run(
|
|
96
|
+
lambda: values.append("verified"),
|
|
97
|
+
action=action.capability, params=action.params, intent=action.intent,
|
|
98
|
+
condition=condition, state=state,
|
|
99
|
+
)
|
|
100
|
+
assert values == ["verified"]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
A callback's code must actually implement its supplied action description.
|
|
104
|
+
For an untrusted agent, use a registered broker operation that constructs and
|
|
105
|
+
executes the same canonical parameters. The bundled MCP operation creates a new
|
|
106
|
+
small UTF-8 marker in its own sandbox; it cannot run a shell or overwrite files.
|
|
107
|
+
|
|
108
|
+
## What is enforced
|
|
109
|
+
|
|
110
|
+
An authorization binds an action hash, capability, condition hash, state hash,
|
|
111
|
+
nonce, issue time, and expiry. Ed25519 verification and a durable SQLite replay
|
|
112
|
+
claim happen before execution. Execution is never retried. Missing, malformed,
|
|
113
|
+
forged, expired, replayed, or mismatched authorization fails closed.
|
|
114
|
+
|
|
115
|
+
This guarantee applies to mediated capabilities. Arbitrary host tools are outside
|
|
116
|
+
the broker. Local same-user key storage supports development and CI; a malicious
|
|
117
|
+
process able to read the signer, change the gate, or mutate the ledger can bypass
|
|
118
|
+
that trust boundary. Production credentials and signing authority require process
|
|
119
|
+
or account isolation from untrusted agent code. Instructions and hooks are not a
|
|
120
|
+
universal security boundary.
|
|
121
|
+
|
|
122
|
+
## Research is measured separately
|
|
123
|
+
|
|
124
|
+
`GATE_BLOCK` is deterministic enforcement, not native EOS. Successful empty
|
|
125
|
+
provider output is classified as a black-box `PROVIDER_VOID` with V0/V1/V2/VU
|
|
126
|
+
subtypes. Only exposed native token evidence can qualify as `NATIVE_VOID`.
|
|
127
|
+
The package does not download or retrain research models. The frozen
|
|
128
|
+
[PCCG-2 release](https://getswiftapi.com/pccg-2) and
|
|
129
|
+
[research library](https://getswiftapi.com/research) preserve the empirical,
|
|
130
|
+
causal, theoretical, and protocol boundaries.
|
|
131
|
+
|
|
132
|
+
## Documentation
|
|
133
|
+
|
|
134
|
+
Start with [Quickstart](docs/QUICKSTART.md). See [concepts](docs/CONCEPTS.md),
|
|
135
|
+
[local brake](docs/LOCAL_BRAKE.md), [Codex](docs/CODEX.md),
|
|
136
|
+
[Claude Code](docs/CLAUDE_CODE.md), [Python SDK](docs/PYTHON_SDK.md),
|
|
137
|
+
[conditions](docs/CONDITIONS.md), [action envelopes](docs/ACTION_ENVELOPES.md),
|
|
138
|
+
[receipts](docs/RECEIPTS.md), [verification](docs/VERIFICATION.md),
|
|
139
|
+
[remote authority](docs/REMOTE_SWIFTAPI.md), [BYOK](docs/BYOK.md),
|
|
140
|
+
[security](docs/SECURITY_MODEL.md), [threat model](docs/THREAT_MODEL.md),
|
|
141
|
+
[native noncontinuation](docs/NATIVE_NONCONTINUATION.md),
|
|
142
|
+
[benchmarking](docs/BENCHMARKING.md), and [provenance](docs/RESEARCH_PROVENANCE.md).
|
|
143
|
+
|
|
144
|
+
[Migration from 1.2.2](MIGRATION_1_2_2.md) documents security corrections and
|
|
145
|
+
termination-metadata changes. Historical 1.2.2 bytes remain immutable on PyPI.
|
|
146
|
+
|
|
147
|
+
MIT license. Research and software by Rayan Pal / SwiftAPI Labs.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
swiftapi/__init__.py,sha256=oJ91q9TbmnCdPYUuKXPWtW3ne6aQBEo40qANvSWmI_k,1867
|
|
2
|
+
swiftapi/__main__.py,sha256=ee5vE0xcUZM3fPmxicvcw-IJXkm6nOwxARREHBWpF8Q,47
|
|
3
|
+
swiftapi/anthropic.py,sha256=f8lB4XRI4VmCqOLiQaDX5aFNZNzPiR6jheuv40f0umk,8209
|
|
4
|
+
swiftapi/cli.py,sha256=hP9wcYQGQOpwe8LNjdiNQ2GETInRzHumPe5xGhQnCpo,5860
|
|
5
|
+
swiftapi/client.py,sha256=jvAGLGeD-8evyWEWsRGKJZgb_PtQdNgztJR4OQgD48c,11094
|
|
6
|
+
swiftapi/enforcement.py,sha256=EzhR9TVbXe-NqAXxrIfJpg1hSK0gmB9rK--rt2AuL_s,8659
|
|
7
|
+
swiftapi/exceptions.py,sha256=hBleOCc1WwDEM70WNYTy1TDOSOaBJSx3PtzFzfmVOGY,1701
|
|
8
|
+
swiftapi/openai.py,sha256=3eI1T-hF20Apymp6Vkh9jskALmFmQCtzptH4jh9B544,8432
|
|
9
|
+
swiftapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
swiftapi/utils.py,sha256=Sn6ED6ltECCYc-ce9fhxZxgzBthvflPCZelXPPzskZM,3145
|
|
11
|
+
swiftapi/verifier.py,sha256=JkFM9wUFVqy_M98jm4PLWUBtZFTXsItPSGGyZpiqoo0,7058
|
|
12
|
+
swiftapi/brake/__init__.py,sha256=OGhusWHNo8aK1HSsJT6yjEBLpRrQtBJscuRFEj6hv7U,883
|
|
13
|
+
swiftapi/brake/benchmarks.py,sha256=gqURdxdu1FMKCzw8i3c8zXewBzHGdNsMQjiu0DvnFbo,4469
|
|
14
|
+
swiftapi/brake/broker.py,sha256=J5dq9hW1hcBAZ6X1bDkiOr_4R2qZfxQgmTATlwidVF4,10775
|
|
15
|
+
swiftapi/brake/core.py,sha256=_Jd1O-10CVb9-1DzgqCQ3o0D1mvM5SCMlsf6q-bbP6E,14244
|
|
16
|
+
swiftapi/brake/install.py,sha256=VZKGF0r6FfY0CKJ6c_-g_xlGW3TFI4kLooUJq9FYcRM,11137
|
|
17
|
+
swiftapi/brake/mcp.py,sha256=y6VGP37U8IXRYO_bptwo9JOrE6QXkp8Qmojoo32QN6g,5695
|
|
18
|
+
swiftapi/brake/observations.py,sha256=RBkkmzBEzJwq-JG9yYZR9VtsMNocRoOgxCw6iHohG_E,1963
|
|
19
|
+
swiftapi/brake/qualification.py,sha256=tRkx67lKH8c018atUmllWajZwMUccpNf1QptJQIU6ik,4031
|
|
20
|
+
swiftapi/brake/remote.py,sha256=qPj1t0b7uQsQWdTz_3NZz1roxjXH6Mu9ORxVK8amm-4,3150
|
|
21
|
+
swiftapi_python-1.3.0.dist-info/licenses/LICENSE,sha256=btq3h42ZP3swvtQ3ak5k3sP_Y6yRwzL5zrV7EzNeRus,1087
|
|
22
|
+
swiftapi_python-1.3.0.dist-info/METADATA,sha256=FRDqYXMzo9uf9PzJjT9XmyCm64fwc988J-liY3j1qJM,6357
|
|
23
|
+
swiftapi_python-1.3.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
24
|
+
swiftapi_python-1.3.0.dist-info/entry_points.txt,sha256=rIhaU6i_Q2sPz0b8a7Hpe7crjULOwJfxdL1-AIcKRAw,47
|
|
25
|
+
swiftapi_python-1.3.0.dist-info/top_level.txt,sha256=oio-d2BTrT91P7dmufUhlSYjOtWBh4bOYz6rsTDDvu4,9
|
|
26
|
+
swiftapi_python-1.3.0.dist-info/RECORD,,
|