swt3-ai 0.1.0 → 0.4.1
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.
- checksums.yaml +4 -4
- data/README.md +86 -0
- data/lib/swt3_ai/fingerprint.rb +43 -0
- data/lib/swt3_ai/signing.rb +15 -0
- data/lib/swt3_ai/types.rb +27 -0
- data/lib/swt3_ai.rb +7 -3
- metadata +12 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c33738eca6af0da5f3b341aca0c44f10d97f646a0aed85bd57901081c2bc6f9
|
|
4
|
+
data.tar.gz: 26e63c59eb176fc1d7cdfda26eed9841c1fa8e242a97915885a3396f26c43099
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8472c6b851815fd18a8a0f8f1b896b4fd8e727b4a9d4fcc12629beca30294aba4f5b7c95b912d6c5274da0123777bab811fa6723b066b041d228caeae7b292c
|
|
7
|
+
data.tar.gz: f7eda3a4fbeea3e9c58f36cb298f65da87c37bc4798add45af5ac28a81f68776383ee97597a0efb2ed3880aa379976184c0e857dbdb30ccc468cff5897dd6b97
|
data/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Witness your AI. Prove it followed the rules. Cryptographic accountability for every inference, tool call, and resource access.
|
|
2
|
+
|
|
3
|
+
[](https://rubygems.org/gems/swt3-ai)
|
|
4
|
+
[](https://github.com/tenova-labs/swt3-ai/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
# swt3-ai
|
|
7
|
+
|
|
8
|
+
**SWT3 AI Witness SDK for Ruby** (coming soon): tamper-proof evidence that your AI is doing what you say it does. Every inference hashed. Every tool call recorded. Every resource access checked against scope. No prompts or responses ever leave your infrastructure.
|
|
9
|
+
|
|
10
|
+
The EU AI Act takes effect **August 2, 2026**. When regulators ask "prove your AI followed the rules," you need more than logs. You need cryptographic proof.
|
|
11
|
+
|
|
12
|
+
## Status
|
|
13
|
+
|
|
14
|
+
This package reserves the `swt3-ai` namespace on RubyGems. The full Ruby SDK is under development.
|
|
15
|
+
|
|
16
|
+
Production SDKs are available today for Python and TypeScript:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Python
|
|
20
|
+
pip install swt3-ai
|
|
21
|
+
python -m swt3_ai.demo
|
|
22
|
+
|
|
23
|
+
# TypeScript
|
|
24
|
+
npm install @tenova/swt3-ai
|
|
25
|
+
npx swt3-demo
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Both run the full pipeline locally with no API keys: hash, extract, clear, anchor, verify.
|
|
29
|
+
|
|
30
|
+
## What SWT3 Does
|
|
31
|
+
|
|
32
|
+
When your AI makes a call, the SDK:
|
|
33
|
+
|
|
34
|
+
1. **Hashes** the prompt and response locally using SHA-256 (raw text never leaves your machine)
|
|
35
|
+
2. **Extracts** numeric factors: model version, latency, token count, guardrail status
|
|
36
|
+
3. **Clears** sensitive metadata based on your clearing level (you control what goes on the wire)
|
|
37
|
+
4. **Anchors** the factors into a cryptographic fingerprint anyone can independently verify
|
|
38
|
+
5. **Returns** your original response completely untouched
|
|
39
|
+
|
|
40
|
+
The result: an immutable record that your AI ran the right model, with the right guardrails, within the right boundaries. Without the auditor ever seeing the data.
|
|
41
|
+
|
|
42
|
+
## Regulatory Coverage
|
|
43
|
+
|
|
44
|
+
The SWT3 AI Witnessing Profile maps to:
|
|
45
|
+
|
|
46
|
+
- **EU AI Act**: Articles 9, 10, 12, 13, 14, 53, 72
|
|
47
|
+
- **NIST AI RMF**: GOVERN, MAP, MEASURE, MANAGE functions
|
|
48
|
+
- **ISO 42001**: Annex A AI management controls
|
|
49
|
+
- **NIST 800-53**: SI-7 (integrity), AU-2/AU-3 (audit), AC controls
|
|
50
|
+
- **SR 11-7**: Model risk management (financial services)
|
|
51
|
+
|
|
52
|
+
## Verify Any Anchor From Your Terminal
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
echo -n "WITNESS:DEMO_TENANT:AI-INF.1:1:1:0:1774800000000" | sha256sum | cut -c1-12
|
|
56
|
+
# Produces a 12-character fingerprint. Compare it to the anchor. If it matches, the anchor is real.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
No SDK needed. Works on any machine, any language.
|
|
60
|
+
|
|
61
|
+
## Cross-Language Parity
|
|
62
|
+
|
|
63
|
+
All SWT3 SDKs produce identical fingerprints from the same inputs. A unified audit trail across your entire stack, verified by shared test vectors at build time.
|
|
64
|
+
|
|
65
|
+
| Layer | Language | Package |
|
|
66
|
+
|-------|----------|---------|
|
|
67
|
+
| Backend services | Python | [swt3-ai](https://pypi.org/project/swt3-ai/) |
|
|
68
|
+
| API routes / Edge | TypeScript | [@tenova/swt3-ai](https://www.npmjs.com/package/@tenova/swt3-ai) |
|
|
69
|
+
| Protocol reference | TypeScript | [@tenova/libswt3](https://www.npmjs.com/package/@tenova/libswt3) |
|
|
70
|
+
| Web apps (Rails) | Ruby | swt3-ai (this package, coming soon) |
|
|
71
|
+
|
|
72
|
+
## Links
|
|
73
|
+
|
|
74
|
+
- **Website**: [tenova.io](https://tenova.io)
|
|
75
|
+
- **Protocol Spec**: [SWT3-SPEC-v1.0](https://github.com/tenova-labs/swt3-ai)
|
|
76
|
+
- **Live Demo**: [sovereign.tenova.io/audit/axm_audit_demo_eu_ai_act_public](https://sovereign.tenova.io/audit/axm_audit_demo_eu_ai_act_public)
|
|
77
|
+
|
|
78
|
+
## Privacy
|
|
79
|
+
|
|
80
|
+
Your prompts and responses **never leave your infrastructure**. The SDK computes SHA-256 hashes locally and transmits only irreversible hashes and numeric factors. At Clearing Level 3, even the model name is hashed. The witness endpoint is a blind registrar: it stores cryptographic proofs, not your data.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
*SWT3: Sovereign Witness Traceability. We don't run your models. We witness them.*
|
|
85
|
+
|
|
86
|
+
SWT3 and Sovereign Witness Traceability are trademarks of Tenable Nova LLC. Patent pending. Apache 2.0 licensed.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "openssl"
|
|
2
|
+
|
|
3
|
+
module Swt3Ai
|
|
4
|
+
module Fingerprint
|
|
5
|
+
# Mint an SWT3 fingerprint from the canonical formula.
|
|
6
|
+
#
|
|
7
|
+
# Returns the first 12 hex characters of:
|
|
8
|
+
# SHA-256("WITNESS:{tenant}:{proc}:{fa}:{fb}:{fc}:{ts_ms}")
|
|
9
|
+
#
|
|
10
|
+
# This formula is locked and must produce identical output across
|
|
11
|
+
# all SWT3 SDK implementations (Python, TypeScript, Rust, C#, Ruby).
|
|
12
|
+
def self.mint_fingerprint(tenant_id, procedure_id, factor_a, factor_b, factor_c, timestamp_ms)
|
|
13
|
+
input = "WITNESS:#{tenant_id}:#{procedure_id}:#{num_str(factor_a)}:#{num_str(factor_b)}:#{num_str(factor_c)}:#{timestamp_ms}"
|
|
14
|
+
sha256_hex(input, 12)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Compute a truncated SHA-256 hash. Default length is 16 hex characters.
|
|
18
|
+
def self.sha256_truncated(data, length = 16)
|
|
19
|
+
sha256_hex(data, length)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Compute SHA-256 and return the first N hex characters.
|
|
23
|
+
def self.sha256_hex(data, length = 64)
|
|
24
|
+
digest = OpenSSL::Digest::SHA256.hexdigest(data.to_s)
|
|
25
|
+
digest[0, [length, 64].min]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Get the current timestamp in milliseconds and epoch seconds.
|
|
29
|
+
def self.timestamp_ms
|
|
30
|
+
ms = (Time.now.to_f * 1000).to_i
|
|
31
|
+
epoch = ms / 1000
|
|
32
|
+
[ms, epoch]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Format a numeric factor as a string matching the canonical formula.
|
|
36
|
+
# Integer-valued floats are formatted without decimals: 1.0 -> "1"
|
|
37
|
+
def self.num_str(v)
|
|
38
|
+
v == v.to_i ? v.to_i.to_s : v.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private_class_method :num_str
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "openssl"
|
|
2
|
+
|
|
3
|
+
module Swt3Ai
|
|
4
|
+
module Signing
|
|
5
|
+
# Sign a payload with HMAC-SHA256 for non-repudiation.
|
|
6
|
+
#
|
|
7
|
+
# If agent_id is provided, the message is "{fingerprint}:{agent_id}".
|
|
8
|
+
# Otherwise, the message is just the fingerprint.
|
|
9
|
+
# Returns a 64-character lowercase hex string.
|
|
10
|
+
def self.sign_payload(signing_key, anchor_fingerprint, agent_id = nil)
|
|
11
|
+
message = agent_id ? "#{anchor_fingerprint}:#{agent_id}" : anchor_fingerprint
|
|
12
|
+
OpenSSL::HMAC.hexdigest("SHA256", signing_key, message)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Swt3Ai
|
|
2
|
+
# A witness payload ready for transmission to the witness endpoint.
|
|
3
|
+
WitnessPayload = Struct.new(
|
|
4
|
+
:procedure_id, :factor_a, :factor_b, :factor_c,
|
|
5
|
+
:clearing_level, :anchor_fingerprint, :anchor_epoch,
|
|
6
|
+
:fingerprint_timestamp_ms, :ai_model_id, :ai_prompt_hash,
|
|
7
|
+
:ai_response_hash, :ai_latency_ms, :ai_input_tokens,
|
|
8
|
+
:ai_output_tokens, :agent_id, :cycle_id,
|
|
9
|
+
:payload_signature, :policy_version_hash,
|
|
10
|
+
keyword_init: true
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# A receipt returned by the witness endpoint after successful anchoring.
|
|
14
|
+
WitnessReceipt = Struct.new(
|
|
15
|
+
:procedure_id, :verdict, :swt3_anchor, :clearing_level,
|
|
16
|
+
:witnessed_at, :verification_url, :ok, :error,
|
|
17
|
+
keyword_init: true
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Configuration for a Witness client.
|
|
21
|
+
WitnessConfig = Struct.new(
|
|
22
|
+
:endpoint, :api_key, :tenant_id, :clearing_level,
|
|
23
|
+
:buffer_size, :flush_interval, :timeout, :max_retries,
|
|
24
|
+
:agent_id, :signing_key, :cycle_id, :policy_version,
|
|
25
|
+
keyword_init: true
|
|
26
|
+
)
|
|
27
|
+
end
|
data/lib/swt3_ai.rb
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
# SWT3 Witness
|
|
2
|
-
# Cryptographic
|
|
1
|
+
# SWT3 AI Witness SDK for Ruby.
|
|
2
|
+
# Cryptographic attestation for AI inference.
|
|
3
3
|
# See https://tenova.io for documentation.
|
|
4
4
|
|
|
5
|
+
require_relative "swt3_ai/fingerprint"
|
|
6
|
+
require_relative "swt3_ai/signing"
|
|
7
|
+
require_relative "swt3_ai/types"
|
|
8
|
+
|
|
5
9
|
module Swt3Ai
|
|
6
|
-
VERSION = "0.
|
|
10
|
+
VERSION = "0.3.6"
|
|
7
11
|
end
|
metadata
CHANGED
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: swt3-ai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TeNova Labs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description:
|
|
14
|
-
|
|
13
|
+
description: Mint, verify, and sign SWT3 witness anchors for AI compliance. Cross-language
|
|
14
|
+
parity with Python and TypeScript SDKs. Zero external dependencies.
|
|
15
15
|
email:
|
|
16
|
+
- engineering@tenovaai.com
|
|
16
17
|
executables: []
|
|
17
18
|
extensions: []
|
|
18
19
|
extra_rdoc_files: []
|
|
19
20
|
files:
|
|
21
|
+
- README.md
|
|
20
22
|
- lib/swt3_ai.rb
|
|
23
|
+
- lib/swt3_ai/fingerprint.rb
|
|
24
|
+
- lib/swt3_ai/signing.rb
|
|
25
|
+
- lib/swt3_ai/types.rb
|
|
21
26
|
homepage: https://tenova.io
|
|
22
27
|
licenses:
|
|
23
28
|
- Apache-2.0
|
|
24
29
|
metadata:
|
|
25
30
|
source_code_uri: https://github.com/tenova-labs/swt3-ai
|
|
31
|
+
homepage_uri: https://tenova.io
|
|
26
32
|
post_install_message:
|
|
27
33
|
rdoc_options: []
|
|
28
34
|
require_paths:
|
|
@@ -31,7 +37,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
31
37
|
requirements:
|
|
32
38
|
- - ">="
|
|
33
39
|
- !ruby/object:Gem::Version
|
|
34
|
-
version:
|
|
40
|
+
version: 2.7.0
|
|
35
41
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
36
42
|
requirements:
|
|
37
43
|
- - ">="
|
|
@@ -41,5 +47,5 @@ requirements: []
|
|
|
41
47
|
rubygems_version: 3.4.20
|
|
42
48
|
signing_key:
|
|
43
49
|
specification_version: 4
|
|
44
|
-
summary: SWT3 Witness
|
|
50
|
+
summary: 'SWT3 AI Witness SDK: cryptographic attestation for AI inference'
|
|
45
51
|
test_files: []
|