spanforge 1.0.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.
- spanforge/__init__.py +815 -0
- spanforge/_ansi.py +93 -0
- spanforge/_batch_exporter.py +409 -0
- spanforge/_cli.py +2094 -0
- spanforge/_cli_audit.py +639 -0
- spanforge/_cli_compliance.py +711 -0
- spanforge/_cli_cost.py +243 -0
- spanforge/_cli_ops.py +791 -0
- spanforge/_cli_phase11.py +356 -0
- spanforge/_hooks.py +337 -0
- spanforge/_server.py +1708 -0
- spanforge/_span.py +1036 -0
- spanforge/_store.py +288 -0
- spanforge/_stream.py +664 -0
- spanforge/_trace.py +335 -0
- spanforge/_tracer.py +254 -0
- spanforge/actor.py +141 -0
- spanforge/alerts.py +469 -0
- spanforge/auto.py +464 -0
- spanforge/baseline.py +335 -0
- spanforge/cache.py +635 -0
- spanforge/compliance.py +325 -0
- spanforge/config.py +532 -0
- spanforge/consent.py +228 -0
- spanforge/consumer.py +377 -0
- spanforge/core/__init__.py +5 -0
- spanforge/core/compliance_mapping.py +1254 -0
- spanforge/cost.py +600 -0
- spanforge/debug.py +548 -0
- spanforge/deprecations.py +205 -0
- spanforge/drift.py +482 -0
- spanforge/egress.py +58 -0
- spanforge/eval.py +648 -0
- spanforge/event.py +1064 -0
- spanforge/exceptions.py +240 -0
- spanforge/explain.py +178 -0
- spanforge/export/__init__.py +69 -0
- spanforge/export/append_only.py +337 -0
- spanforge/export/cloud.py +357 -0
- spanforge/export/datadog.py +497 -0
- spanforge/export/grafana.py +320 -0
- spanforge/export/jsonl.py +195 -0
- spanforge/export/openinference.py +158 -0
- spanforge/export/otel_bridge.py +294 -0
- spanforge/export/otlp.py +811 -0
- spanforge/export/otlp_bridge.py +233 -0
- spanforge/export/redis_backend.py +282 -0
- spanforge/export/siem_schema.py +98 -0
- spanforge/export/siem_splunk.py +264 -0
- spanforge/export/siem_syslog.py +212 -0
- spanforge/export/webhook.py +299 -0
- spanforge/exporters/__init__.py +30 -0
- spanforge/exporters/console.py +271 -0
- spanforge/exporters/jsonl.py +144 -0
- spanforge/exporters/sqlite.py +142 -0
- spanforge/gate.py +1150 -0
- spanforge/governance.py +181 -0
- spanforge/hitl.py +295 -0
- spanforge/http.py +187 -0
- spanforge/inspect.py +427 -0
- spanforge/integrations/__init__.py +45 -0
- spanforge/integrations/_pricing.py +280 -0
- spanforge/integrations/anthropic.py +388 -0
- spanforge/integrations/azure_openai.py +133 -0
- spanforge/integrations/bedrock.py +292 -0
- spanforge/integrations/crewai.py +251 -0
- spanforge/integrations/gemini.py +351 -0
- spanforge/integrations/groq.py +442 -0
- spanforge/integrations/langchain.py +349 -0
- spanforge/integrations/langgraph.py +306 -0
- spanforge/integrations/llamaindex.py +373 -0
- spanforge/integrations/ollama.py +287 -0
- spanforge/integrations/openai.py +368 -0
- spanforge/integrations/together.py +483 -0
- spanforge/io.py +214 -0
- spanforge/lint.py +322 -0
- spanforge/metrics.py +417 -0
- spanforge/metrics_export.py +343 -0
- spanforge/migrate.py +402 -0
- spanforge/model_registry.py +278 -0
- spanforge/models.py +389 -0
- spanforge/namespaces/__init__.py +254 -0
- spanforge/namespaces/audit.py +256 -0
- spanforge/namespaces/cache.py +237 -0
- spanforge/namespaces/chain.py +77 -0
- spanforge/namespaces/confidence.py +72 -0
- spanforge/namespaces/consent.py +92 -0
- spanforge/namespaces/cost.py +179 -0
- spanforge/namespaces/decision.py +143 -0
- spanforge/namespaces/diff.py +157 -0
- spanforge/namespaces/drift.py +80 -0
- spanforge/namespaces/eval_.py +251 -0
- spanforge/namespaces/feedback.py +241 -0
- spanforge/namespaces/fence.py +193 -0
- spanforge/namespaces/guard.py +105 -0
- spanforge/namespaces/hitl.py +91 -0
- spanforge/namespaces/latency.py +72 -0
- spanforge/namespaces/prompt.py +190 -0
- spanforge/namespaces/redact.py +173 -0
- spanforge/namespaces/retrieval.py +379 -0
- spanforge/namespaces/runtime_governance.py +494 -0
- spanforge/namespaces/template.py +208 -0
- spanforge/namespaces/tool_call.py +77 -0
- spanforge/namespaces/trace.py +1029 -0
- spanforge/normalizer.py +171 -0
- spanforge/plugins.py +82 -0
- spanforge/presidio_backend.py +349 -0
- spanforge/processor.py +258 -0
- spanforge/prompt_registry.py +418 -0
- spanforge/py.typed +0 -0
- spanforge/redact.py +914 -0
- spanforge/regression.py +192 -0
- spanforge/runtime_policy.py +159 -0
- spanforge/sampling.py +511 -0
- spanforge/schema.py +183 -0
- spanforge/schemas/v1.0/schema.json +170 -0
- spanforge/schemas/v2.0/schema.json +536 -0
- spanforge/sdk/__init__.py +625 -0
- spanforge/sdk/_base.py +584 -0
- spanforge/sdk/_base.pyi +71 -0
- spanforge/sdk/_exceptions.py +1096 -0
- spanforge/sdk/_types.py +2184 -0
- spanforge/sdk/alert.py +1514 -0
- spanforge/sdk/alert.pyi +56 -0
- spanforge/sdk/audit.py +1196 -0
- spanforge/sdk/audit.pyi +67 -0
- spanforge/sdk/cec.py +1215 -0
- spanforge/sdk/cec.pyi +37 -0
- spanforge/sdk/config.py +641 -0
- spanforge/sdk/config.pyi +55 -0
- spanforge/sdk/enterprise.py +714 -0
- spanforge/sdk/enterprise.pyi +79 -0
- spanforge/sdk/explain.py +170 -0
- spanforge/sdk/fallback.py +432 -0
- spanforge/sdk/feedback.py +351 -0
- spanforge/sdk/gate.py +874 -0
- spanforge/sdk/gate.pyi +51 -0
- spanforge/sdk/identity.py +2114 -0
- spanforge/sdk/identity.pyi +47 -0
- spanforge/sdk/lineage.py +175 -0
- spanforge/sdk/observe.py +1065 -0
- spanforge/sdk/observe.pyi +50 -0
- spanforge/sdk/operator.py +338 -0
- spanforge/sdk/pii.py +1473 -0
- spanforge/sdk/pii.pyi +119 -0
- spanforge/sdk/pipelines.py +458 -0
- spanforge/sdk/pipelines.pyi +39 -0
- spanforge/sdk/policy.py +930 -0
- spanforge/sdk/rag.py +594 -0
- spanforge/sdk/rbac.py +280 -0
- spanforge/sdk/registry.py +430 -0
- spanforge/sdk/registry.pyi +46 -0
- spanforge/sdk/scope.py +279 -0
- spanforge/sdk/secrets.py +293 -0
- spanforge/sdk/secrets.pyi +25 -0
- spanforge/sdk/security.py +560 -0
- spanforge/sdk/security.pyi +57 -0
- spanforge/sdk/trust.py +472 -0
- spanforge/sdk/trust.pyi +41 -0
- spanforge/secrets.py +799 -0
- spanforge/signing.py +1179 -0
- spanforge/stats.py +100 -0
- spanforge/stream.py +560 -0
- spanforge/testing.py +378 -0
- spanforge/testing_mocks.py +1052 -0
- spanforge/trace.py +199 -0
- spanforge/types.py +696 -0
- spanforge/ulid.py +300 -0
- spanforge/validate.py +379 -0
- spanforge-1.0.0.dist-info/METADATA +1509 -0
- spanforge-1.0.0.dist-info/RECORD +174 -0
- spanforge-1.0.0.dist-info/WHEEL +4 -0
- spanforge-1.0.0.dist-info/entry_points.txt +5 -0
- spanforge-1.0.0.dist-info/licenses/LICENSE +128 -0
|
@@ -0,0 +1,1509 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: spanforge
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: SpanForge — AI lifecycle and governance platform (RFC-0001 SPANFORGE)
|
|
5
|
+
Project-URL: Homepage, https://github.com/veerarag1973/spanforge
|
|
6
|
+
Project-URL: Documentation, https://github.com/veerarag1973/spanforge/blob/main/docs/index.md
|
|
7
|
+
Project-URL: Source, https://github.com/veerarag1973/spanforge
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/veerarag1973/spanforge/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/veerarag1973/spanforge/blob/main/docs/changelog.md
|
|
10
|
+
Author: viswanathanstartup
|
|
11
|
+
License: PolyForm-Noncommercial-1.0.0
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: agentic-ai,ai-compliance,ai-lifecycle,events,governance,llm,opentelemetry,schema,spanforge
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: Other/Proprietary License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: System :: Logging
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: anthropic>=0.25; extra == 'all'
|
|
29
|
+
Requires-Dist: crewai>=0.28; extra == 'all'
|
|
30
|
+
Requires-Dist: cryptography>=46.0.7; extra == 'all'
|
|
31
|
+
Requires-Dist: httpx>=0.27; extra == 'all'
|
|
32
|
+
Requires-Dist: jsonschema>=4.21; extra == 'all'
|
|
33
|
+
Requires-Dist: kafka-python>=2.0; extra == 'all'
|
|
34
|
+
Requires-Dist: langchain-core>=0.2; extra == 'all'
|
|
35
|
+
Requires-Dist: langgraph>=0.2; extra == 'all'
|
|
36
|
+
Requires-Dist: llama-index-core>=0.10; extra == 'all'
|
|
37
|
+
Requires-Dist: openai>=1.0; extra == 'all'
|
|
38
|
+
Requires-Dist: opentelemetry-sdk>=1.24; extra == 'all'
|
|
39
|
+
Requires-Dist: pydantic>=2.7; extra == 'all'
|
|
40
|
+
Requires-Dist: redis>=4.0; extra == 'all'
|
|
41
|
+
Provides-Extra: anthropic
|
|
42
|
+
Requires-Dist: anthropic>=0.25; extra == 'anthropic'
|
|
43
|
+
Provides-Extra: bedrock
|
|
44
|
+
Requires-Dist: boto3>=1.34; extra == 'bedrock'
|
|
45
|
+
Provides-Extra: compliance
|
|
46
|
+
Requires-Dist: reportlab>=4.0; extra == 'compliance'
|
|
47
|
+
Provides-Extra: crewai
|
|
48
|
+
Requires-Dist: crewai>=0.28; extra == 'crewai'
|
|
49
|
+
Provides-Extra: datadog
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
52
|
+
Requires-Dist: hypothesis>=6.100; extra == 'dev'
|
|
53
|
+
Requires-Dist: jsonschema>=4.21; extra == 'dev'
|
|
54
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
55
|
+
Requires-Dist: pre-commit>=3.7; extra == 'dev'
|
|
56
|
+
Requires-Dist: pydantic>=2.7; extra == 'dev'
|
|
57
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
58
|
+
Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
|
|
59
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
60
|
+
Requires-Dist: pytest-xdist>=3.5; extra == 'dev'
|
|
61
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
62
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
63
|
+
Provides-Extra: docs
|
|
64
|
+
Requires-Dist: pydata-sphinx-theme>=0.15; extra == 'docs'
|
|
65
|
+
Requires-Dist: sphinx>=7.0; extra == 'docs'
|
|
66
|
+
Provides-Extra: gemini
|
|
67
|
+
Requires-Dist: google-generativeai>=0.5; extra == 'gemini'
|
|
68
|
+
Provides-Extra: groq
|
|
69
|
+
Requires-Dist: groq>=0.9; extra == 'groq'
|
|
70
|
+
Provides-Extra: http
|
|
71
|
+
Requires-Dist: httpx>=0.27; extra == 'http'
|
|
72
|
+
Provides-Extra: identity
|
|
73
|
+
Requires-Dist: cryptography>=46.0.7; extra == 'identity'
|
|
74
|
+
Provides-Extra: jsonschema
|
|
75
|
+
Requires-Dist: jsonschema>=4.21; extra == 'jsonschema'
|
|
76
|
+
Provides-Extra: kafka
|
|
77
|
+
Requires-Dist: kafka-python>=2.0; extra == 'kafka'
|
|
78
|
+
Provides-Extra: langchain
|
|
79
|
+
Requires-Dist: langchain-core>=0.2; extra == 'langchain'
|
|
80
|
+
Provides-Extra: langgraph
|
|
81
|
+
Requires-Dist: langgraph>=0.2; extra == 'langgraph'
|
|
82
|
+
Provides-Extra: llamaindex
|
|
83
|
+
Requires-Dist: llama-index-core>=0.10; extra == 'llamaindex'
|
|
84
|
+
Provides-Extra: ollama
|
|
85
|
+
Requires-Dist: ollama>=0.2; extra == 'ollama'
|
|
86
|
+
Provides-Extra: openai
|
|
87
|
+
Requires-Dist: openai>=1.0; extra == 'openai'
|
|
88
|
+
Provides-Extra: otel
|
|
89
|
+
Requires-Dist: opentelemetry-sdk>=1.24; extra == 'otel'
|
|
90
|
+
Provides-Extra: presidio
|
|
91
|
+
Requires-Dist: presidio-analyzer>=2.2; extra == 'presidio'
|
|
92
|
+
Requires-Dist: presidio-anonymizer>=2.2; extra == 'presidio'
|
|
93
|
+
Provides-Extra: pydantic
|
|
94
|
+
Requires-Dist: pydantic>=2.7; extra == 'pydantic'
|
|
95
|
+
Provides-Extra: redis
|
|
96
|
+
Requires-Dist: redis>=4.0; extra == 'redis'
|
|
97
|
+
Provides-Extra: together
|
|
98
|
+
Requires-Dist: together>=1.2; extra == 'together'
|
|
99
|
+
Provides-Extra: worm-gcs
|
|
100
|
+
Requires-Dist: google-cloud-storage>=2.14; extra == 'worm-gcs'
|
|
101
|
+
Provides-Extra: worm-s3
|
|
102
|
+
Requires-Dist: boto3>=1.34; extra == 'worm-s3'
|
|
103
|
+
Description-Content-Type: text/markdown
|
|
104
|
+
|
|
105
|
+
<h1 align="center">spanforge</h1>
|
|
106
|
+
|
|
107
|
+
<p align="center">
|
|
108
|
+
<strong>The AI Compliance Platform for Agentic Systems.</strong><br/>
|
|
109
|
+
Ship AI applications that are auditable, regulator-ready, and privacy-safe — from day one.
|
|
110
|
+
</p>
|
|
111
|
+
|
|
112
|
+
<p align="center">
|
|
113
|
+
<em>Built on <a href="https://www.getspanforge.com/standard">RFC-0001 — the SpanForge AI Compliance Standard</a> for agentic AI systems.</em>
|
|
114
|
+
</p>
|
|
115
|
+
|
|
116
|
+
<p align="center">
|
|
117
|
+
<img src="https://img.shields.io/badge/python-3.9%2B-4c8cbf?logo=python&logoColor=white" alt="Python 3.9+"/>
|
|
118
|
+
<a href="https://pypi.org/project/spanforge/"><img src="https://img.shields.io/pypi/v/spanforge?color=4c8cbf&logo=pypi&logoColor=white" alt="PyPI"/></a>
|
|
119
|
+
<a href="https://www.getspanforge.com/standard"><img src="https://img.shields.io/badge/standard-SpanForge_RFC--0001-4c8cbf" alt="spanforge RFC-0001"/></a>
|
|
120
|
+
<img src="https://img.shields.io/badge/coverage-90.96%25-brightgreen" alt="90.96% test coverage"/>
|
|
121
|
+
<img src="https://img.shields.io/badge/tests-6138%20passing-brightgreen" alt="6138 tests"/>
|
|
122
|
+
<img src="https://img.shields.io/badge/version-1.0.0-4c8cbf" alt="Version 1.0.0"/>
|
|
123
|
+
<img src="https://img.shields.io/badge/dependencies-zero-brightgreen" alt="Zero dependencies"/>
|
|
124
|
+
<a href="docs/index.md"><img src="https://img.shields.io/badge/docs-local-4c8cbf" alt="Documentation"/></a>
|
|
125
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-PolyForm%20NC%201.0-blue" alt="PolyForm Noncommercial 1.0"/></a>
|
|
126
|
+
<img src="https://img.shields.io/badge/free%20for-personal%20%7C%20research%20%7C%20open--source-brightgreen" alt="Free for personal, research, and open-source use"/>
|
|
127
|
+
<a href="https://getspanforge.com/pricing"><img src="https://img.shields.io/badge/commercial%20use-license%20required-orange" alt="Commercial use requires a license"/></a>
|
|
128
|
+
</p>
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## The problem
|
|
133
|
+
|
|
134
|
+
You're building AI applications in a world where regulators are catching up fast. The EU AI Act is in force. GDPR applies to every LLM that touches personal data. SOC 2 auditors want evidence that your AI systems are governed. And your team is stitching together ad-hoc logs, hoping they'll hold up in an audit.
|
|
135
|
+
|
|
136
|
+
**spanforge** solves this. It is a **compliance-first platform** — not a monitoring add-on — that gives every AI action in your stack a cryptographically signed, privacy-safe, regulator-ready record.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## If you're a solo developer or early-stage startup
|
|
141
|
+
|
|
142
|
+
You might think compliance is a later problem — something to worry about when you have a legal team. Here's why it isn't:
|
|
143
|
+
|
|
144
|
+
- **You'll hit it sooner than you think.** The first B2B customer, the first SaaS sign-up from an EU user, the first healthcare or fintech pilot — they'll ask "how do you govern your AI?" If you have no answer, you lose the deal.
|
|
145
|
+
- **Retrofitting is expensive.** Adding audit trails, PII scrubbing, and signed evidence chains to an existing system takes weeks. Adding them with spanforge from day one takes minutes.
|
|
146
|
+
- **It's zero-cost to start.** The entire SDK is free for noncommercial use, zero dependencies, and works in-memory with no infrastructure. You don't pay anything until you need hosted storage.
|
|
147
|
+
- **It de-risks you personally.** GDPR fines apply to individuals running services, not just corporations. PII redaction and tamper-proof logs are your protection too.
|
|
148
|
+
|
|
149
|
+
In short: spanforge is the `logging` import you should have added on day one — except it also signs your audit trail and maps it to the regulations that will eventually matter to you.
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
pip install spanforge # free for noncommercial use, zero deps
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
import spanforge
|
|
157
|
+
spanforge.configure() # that's it — you're now compliant-by-default
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## What spanforge does
|
|
163
|
+
|
|
164
|
+
<table>
|
|
165
|
+
<tr>
|
|
166
|
+
<td width="50%">
|
|
167
|
+
|
|
168
|
+
### Compliance & Regulatory Mapping
|
|
169
|
+
- Map telemetry to **EU AI Act**, **GDPR**, **SOC 2**, **HIPAA**, **ISO 42001**, **NIST AI RMF** clauses automatically
|
|
170
|
+
- Generate HMAC-signed **evidence packages** with gap analysis
|
|
171
|
+
- Track **consent boundaries**, **HITL oversight**, **model registry** governance, and **explainability** coverage
|
|
172
|
+
- Produce audit-ready attestations with model owner, risk tier, and status metadata
|
|
173
|
+
- **Compliance Evidence Chain (sf-cec)** — signed ZIP bundles with regulatory clause maps, DPA generation, and RFC 3161 timestamps for auditor hand-off
|
|
174
|
+
- **Observability SDK (sf-observe)** — span export (OTLP/Datadog/Grafana/Splunk/Elastic), W3C TraceContext, OTel GenAI attrs, sampling strategies, annotation store, and health probes
|
|
175
|
+
- **CI/CD Gate Pipeline (sf-gate)** — evaluate release quality gates (schema, secrets, performance, PRRI, trust), YAML pipeline engine, artifact store, and blocking trust gate to prevent unsafe releases
|
|
176
|
+
- **T.R.U.S.T. Scorecard (sf-trust)** — five-pillar trust dimensions (Transparency · Reliability · UserTrust · Security · Traceability), configurable weights, SVG badge, history time-series, and 5 HallucCheck pipeline integrations (score, bias, monitor, risk, benchmark)
|
|
177
|
+
- **Enterprise Hardening (sf-enterprise)** — multi-tenancy with project-level isolation, data residency enforcement (EU/US/AP/IN), AES-256-GCM encryption at rest, envelope encryption via cloud KMS, mTLS, FIPS 140-2 mode, air-gap offline mode, and container health endpoints
|
|
178
|
+
- **Security Review (sf-security)** — OWASP API Security Top 10 audit, STRIDE threat modelling, dependency vulnerability scanning, static analysis, and secrets-in-logs detection
|
|
179
|
+
|
|
180
|
+
</td>
|
|
181
|
+
<td width="50%">
|
|
182
|
+
|
|
183
|
+
### Privacy & Audit Infrastructure- **Secrets scanning** — 20-pattern registry detects API keys, tokens, private keys; SARIF output; pre-commit hook- **PII redaction** — detect and strip sensitive data before it leaves your app. Includes a Presidio NLP backend (`spanforge[presidio]`) covering 15 entity types (SSN, email, phone, AADHAAR, PAN, UK NI, credit card, IBAN, and more) with ≥ 95% true-positive rate and < 0.5% false-positive rate verified at GA
|
|
184
|
+
- **HMAC audit chains** — tamper-evident, blockchain-style event signing- **Audit SDK (`sf-audit`)** — `sf_audit.append()`, schema key registry, T.R.U.S.T. scorecard, GDPR Article 30 RoPA, BYOS cloud routing- **GDPR subject erasure** — right-to-erasure with tombstone events that preserve chain integrity
|
|
185
|
+
- **Air-gapped deployment** — runs fully offline with zero egress
|
|
186
|
+
|
|
187
|
+
</td>
|
|
188
|
+
</tr>
|
|
189
|
+
<tr>
|
|
190
|
+
<td>
|
|
191
|
+
|
|
192
|
+
### Governance & Controls
|
|
193
|
+
- **Consent boundary monitoring** — `consent.granted`, `consent.revoked`, `consent.violation` events
|
|
194
|
+
- **Human-in-the-loop hooks** — `hitl.queued`, `hitl.reviewed`, `hitl.escalated`, `hitl.timeout` events
|
|
195
|
+
- **Model registry** — register, deprecate, retire models; attestations auto-warn on ungoverned models
|
|
196
|
+
- **Explainability tracking** — measure what % of AI decisions have explanations attached
|
|
197
|
+
|
|
198
|
+
</td>
|
|
199
|
+
<td>
|
|
200
|
+
|
|
201
|
+
### Developer Experience
|
|
202
|
+
- **Zero required dependencies** — pure Python 3.9+ stdlib
|
|
203
|
+
- **One-line setup** — `spanforge.configure()` and you're compliant
|
|
204
|
+
- **Integration config** — `.halluccheck.toml` config block, service registry, local fallbacks for all 11 services
|
|
205
|
+
- **T.R.U.S.T. Scorecard (sf-trust)** — five-pillar trust assessment (Transparency, Reliability, UserTrust, Security, Traceability), SVG badge generation, HallucCheck pipeline integrations
|
|
206
|
+
- **Mock library** — `spanforge.testing_mocks` — 11 drop-in mock service clients + `mock_all_services()` context manager for zero-network unit tests
|
|
207
|
+
- **Sandbox mode** — `[spanforge] sandbox = true` routes all service calls to local in-memory sandbox
|
|
208
|
+
- **`spanforge doctor`** — environment diagnostics: config valid, services reachable, patterns loaded, gate YAML valid
|
|
209
|
+
- **Auto-instrumentation** — patch OpenAI, Anthropic, LangChain, CrewAI, and more; `@trace_rag` decorator and automatic LlamaIndex/LangChain retriever instrumentation for zero-change RAG tracing
|
|
210
|
+
- **Async SDK** — every major SDK method now has a non-blocking `*_async()` variant (`scan_async`, `evaluate_async`, `build_bundle_async`, `get_scorecard_async`, `sso_delegate_session_async`) for seamless use in async frameworks
|
|
211
|
+
- **User feedback REST endpoint** — `POST /v1/feedback` accepts star/thumbs/Likert ratings and free-text comments (SHA-256 hashed); links to T.R.U.S.T. dimensions
|
|
212
|
+
- **33 CLI commands** — compliance checks, PII scans, secrets scanning, audit-chain verification, CI/CD gate pipelines, trust scorecards, config validation, enterprise health, security scanning, doctor diagnostics, all CI-ready
|
|
213
|
+
|
|
214
|
+
</td>
|
|
215
|
+
</tr>
|
|
216
|
+
</table>
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## How it compares
|
|
221
|
+
|
|
222
|
+
spanforge is the only **open-standard, zero-dependency AI compliance platform**. Other tools are monitoring platforms that bolt on compliance as an afterthought. spanforge is compliance infrastructure that happens to capture the telemetry needed to prove it.
|
|
223
|
+
|
|
224
|
+
| Capability | **spanforge** | LangSmith | Langfuse | OpenLLMetry | Arize Phoenix |
|
|
225
|
+
|---|:---:|:---:|:---:|:---:|:---:|
|
|
226
|
+
| Regulatory framework mapping (EU AI Act, GDPR, SOC 2…) | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
227
|
+
| HMAC-signed evidence packages & attestations | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
228
|
+
| Consent boundary monitoring | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
229
|
+
| Human-in-the-loop compliance events | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
230
|
+
| Model registry with risk-tier governance | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
231
|
+
| Explainability coverage metrics | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
232
|
+
| Built-in PII redaction | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
233
|
+
| Tamper-proof audit chain | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
234
|
+
| GDPR subject erasure (right-to-erasure) | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
235
|
+
| Works fully offline / air-gapped | ✅ | ❌ | Self-host | Partial | Self-host |
|
|
236
|
+
| Open schema standard (RFC-driven) | ✅ | ❌ | ❌ | Partial | ❌ |
|
|
237
|
+
| Zero required dependencies | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
238
|
+
| OTLP export (any OTel backend) | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|
239
|
+
| Source-available, no call-home | ✅ | Partial | ✅ | ✅ | ✅ |
|
|
240
|
+
| CI/CD release quality gates (schema, secrets, PRRI, trust gate) | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
241
|
+
|
|
242
|
+
> **Bottom line**: Others help you *watch* your AI. spanforge helps you *govern* it.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Install
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
pip install spanforge
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Requires Python 3.9+.** Zero mandatory dependencies.
|
|
253
|
+
|
|
254
|
+
Documented CLI entrypoints, version consistency, and known stale doc patterns
|
|
255
|
+
are also checked in CI so public docs drift fails fast during PR validation.
|
|
256
|
+
|
|
257
|
+
### Optional extras
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
pip install "spanforge[openai]" # OpenAI auto-instrumentation
|
|
261
|
+
pip install "spanforge[langchain]" # LangChain callback handler
|
|
262
|
+
pip install "spanforge[crewai]" # CrewAI callback handler
|
|
263
|
+
pip install "spanforge[http]" # Webhook + OTLP export
|
|
264
|
+
pip install "spanforge[datadog]" # Datadog APM + metrics
|
|
265
|
+
pip install "spanforge[kafka]" # Kafka EventStream source
|
|
266
|
+
pip install "spanforge[pydantic]" # Pydantic v2 model layer
|
|
267
|
+
pip install "spanforge[otel]" # OpenTelemetry SDK integration
|
|
268
|
+
pip install "spanforge[jsonschema]" # Strict JSON Schema validation
|
|
269
|
+
pip install "spanforge[llamaindex]" # LlamaIndex event handler
|
|
270
|
+
pip install "spanforge[gemini]" # Google Gemini auto-instrumentation
|
|
271
|
+
pip install "spanforge[bedrock]" # AWS Bedrock Converse API
|
|
272
|
+
pip install "spanforge[presidio]" # Presidio-powered PII detection
|
|
273
|
+
pip install "spanforge[all]" # everything above
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Runtime Governance GA Surface
|
|
279
|
+
|
|
280
|
+
The GA implementation spine is the runtime-governance control plane:
|
|
281
|
+
|
|
282
|
+
- `sf_explain` for signed runtime explanations
|
|
283
|
+
- `sf_scope` for agent capability enforcement
|
|
284
|
+
- `sf_rbac` for role enforcement on sensitive actions
|
|
285
|
+
- `sf_rag` for grounding evidence and thresholds
|
|
286
|
+
- `sf_lineage` for provenance capture
|
|
287
|
+
- `sf_policy` for policy activation, replay, simulation, and review
|
|
288
|
+
- `sf_operator` for trace inspection and signed operator exports
|
|
289
|
+
- `sf_enterprise` for deployment posture and enterprise evidence packaging
|
|
290
|
+
|
|
291
|
+
Start here if you want the end-to-end story instead of the full product surface:
|
|
292
|
+
|
|
293
|
+
- [docs/runtime-governance.md](docs/runtime-governance.md)
|
|
294
|
+
- [docs/runtime-governance-contracts.md](docs/runtime-governance-contracts.md)
|
|
295
|
+
- [docs/replay-simulation.md](docs/replay-simulation.md)
|
|
296
|
+
- [docs/evidence-export.md](docs/evidence-export.md)
|
|
297
|
+
- [docs/enterprise-integrations.md](docs/enterprise-integrations.md)
|
|
298
|
+
- [docs/competitor-comparison.md](docs/competitor-comparison.md)
|
|
299
|
+
- [docs/ga-release-notes.md](docs/ga-release-notes.md)
|
|
300
|
+
- [docs/demos/runtime-governance-demo.md](docs/demos/runtime-governance-demo.md)
|
|
301
|
+
- [docs/demos/enterprise-evidence-demo.md](docs/demos/enterprise-evidence-demo.md)
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Quick start — compliance in 5 minutes
|
|
306
|
+
|
|
307
|
+
### 1. Configure and instrument
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
import spanforge
|
|
311
|
+
|
|
312
|
+
spanforge.configure(
|
|
313
|
+
service_name="my-agent",
|
|
314
|
+
signing_key="your-org-secret", # HMAC audit chain — tamper-proof
|
|
315
|
+
redaction_policy="gdpr", # PII stripped before export
|
|
316
|
+
exporter="jsonl",
|
|
317
|
+
endpoint="audit.jsonl",
|
|
318
|
+
)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Every event your app emits is now **signed**, **PII-redacted**, and **stored** — with zero per-call boilerplate.
|
|
322
|
+
|
|
323
|
+
### 2. Trace AI decisions
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
with spanforge.start_trace("loan-approval-agent") as trace:
|
|
327
|
+
with trace.llm_call("gpt-4o", temperature=0.2) as span:
|
|
328
|
+
decision = call_llm(prompt)
|
|
329
|
+
span.set_token_usage(input=512, output=200, total=712)
|
|
330
|
+
span.set_status("ok")
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### 3. Generate compliance evidence
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
from spanforge.core.compliance_mapping import ComplianceMappingEngine
|
|
337
|
+
|
|
338
|
+
engine = ComplianceMappingEngine()
|
|
339
|
+
package = engine.generate_evidence_package(
|
|
340
|
+
model_id="gpt-4o",
|
|
341
|
+
framework="eu_ai_act",
|
|
342
|
+
from_date="2026-01-01",
|
|
343
|
+
to_date="2026-03-31",
|
|
344
|
+
audit_events=events,
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
print(package.attestation.coverage_pct) # e.g. 87.5%
|
|
348
|
+
print(package.attestation.explanation_coverage_pct) # e.g. 75.0%
|
|
349
|
+
print(package.attestation.model_risk_tier) # e.g. "high"
|
|
350
|
+
print(package.gap_report) # what's missing
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Or from the CLI:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
spanforge compliance generate \
|
|
357
|
+
--model-id gpt-4o \
|
|
358
|
+
--framework eu_ai_act \
|
|
359
|
+
--from 2026-01-01 --to 2026-03-31 \
|
|
360
|
+
--events-file audit.jsonl
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### 4. Hand to your auditor
|
|
364
|
+
|
|
365
|
+
The evidence package contains:
|
|
366
|
+
- **Clause mappings** — which telemetry events satisfy which regulatory clauses
|
|
367
|
+
- **Gap analysis** — which clauses lack evidence and need attention
|
|
368
|
+
- **HMAC-signed attestation** — cryptographic proof the evidence hasn't been tampered with
|
|
369
|
+
- **Model governance metadata** — owner, risk tier, status, warnings for deprecated/retired models
|
|
370
|
+
- **Explanation coverage** — percentage of AI decisions with explainability records
|
|
371
|
+
### 5. Package for auditors with sf-cec (v2.0.4+)
|
|
372
|
+
|
|
373
|
+
Bundle your audit records into a regulator-ready, HMAC-signed ZIP:
|
|
374
|
+
|
|
375
|
+
```python
|
|
376
|
+
from spanforge.sdk import sf_cec
|
|
377
|
+
|
|
378
|
+
# Build a compliance evidence bundle for Q1 2026
|
|
379
|
+
result = sf_cec.build_bundle(
|
|
380
|
+
project_id="my-agent",
|
|
381
|
+
date_range=("2026-01-01", "2026-03-31"),
|
|
382
|
+
frameworks=["eu_ai_act", "iso_42001", "soc2"],
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
print(result.bundle_id) # sfcec_my-agent_20260401T000000Z_abc123
|
|
386
|
+
print(result.zip_path) # /tmp/sfcec/halluccheck_cec_my-agent_2026-01-01_2026-03-31.zip
|
|
387
|
+
print(result.hmac_manifest) # hmac-sha256:a3f9…
|
|
388
|
+
print(result.record_counts) # {"halluccheck.score.v1": 214, "halluccheck.bias.v1": 87, …}
|
|
389
|
+
|
|
390
|
+
# Verify bundle integrity before sharing
|
|
391
|
+
verify = sf_cec.verify_bundle(result.zip_path)
|
|
392
|
+
assert verify.overall_valid
|
|
393
|
+
|
|
394
|
+
# Generate a GDPR Art. 28 Data Processing Agreement
|
|
395
|
+
dpa = sf_cec.generate_dpa(
|
|
396
|
+
project_id="my-agent",
|
|
397
|
+
controller_details={"name": "Acme Corp", "contact": "dpo@acme.com"},
|
|
398
|
+
processor_details={"name": "ML Platform Team"},
|
|
399
|
+
)
|
|
400
|
+
print(dpa.document_id) # sfcec-dpa-my-agent-20260401
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
The ZIP bundle contains:
|
|
404
|
+
- `manifest.json` — record inventory with HMAC-SHA256 signature
|
|
405
|
+
- `clause_map.json` — per-framework clause satisfaction (SATISFIED / PARTIAL / GAP)
|
|
406
|
+
- `chain_proof.json` — audit chain verification result
|
|
407
|
+
- `attestation.json` — HMAC-signed attestation metadata
|
|
408
|
+
- `rfc3161_timestamp.tsr` — trusted timestamp stub (RFC 3161)
|
|
409
|
+
- `score_records/`, `bias_reports/`, `prri_records/`, `drift_events/`, `pii_detections/`, `gate_evaluations/` — NDJSON evidence per schema key
|
|
410
|
+
|
|
411
|
+
### 6. Observe spans with sf-observe (v2.0.5+)
|
|
412
|
+
|
|
413
|
+
Export spans to any OTLP-compatible backend, emit structured annotations, and
|
|
414
|
+
trace LLM calls with OTel GenAI semantic conventions:
|
|
415
|
+
|
|
416
|
+
```python
|
|
417
|
+
from spanforge.sdk import sf_observe
|
|
418
|
+
|
|
419
|
+
# Emit a span for an LLM call — W3C traceparent + OTel GenAI attrs added automatically
|
|
420
|
+
span_id = sf_observe.emit_span(
|
|
421
|
+
"chat.completion",
|
|
422
|
+
{
|
|
423
|
+
"gen_ai.system": "openai",
|
|
424
|
+
"gen_ai.request.model": "gpt-4o",
|
|
425
|
+
"gen_ai.usage.input_tokens": 512,
|
|
426
|
+
"gen_ai.usage.output_tokens": 64,
|
|
427
|
+
},
|
|
428
|
+
)
|
|
429
|
+
print(span_id) # "a3f1b2c4d5e6f708"
|
|
430
|
+
|
|
431
|
+
# Mark a model deployment
|
|
432
|
+
annotation_id = sf_observe.add_annotation(
|
|
433
|
+
"model_deployed",
|
|
434
|
+
{"model": "gpt-4o", "environment": "production"},
|
|
435
|
+
project_id="my-agent",
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
# Health probe
|
|
439
|
+
print(sf_observe.healthy) # True
|
|
440
|
+
print(sf_observe.last_export_at) # ISO-8601 or None
|
|
441
|
+
|
|
442
|
+
# Export to any OTLP endpoint per-call
|
|
443
|
+
from spanforge.sdk import ReceiverConfig
|
|
444
|
+
result = sf_observe.export_spans(
|
|
445
|
+
my_spans,
|
|
446
|
+
receiver_config=ReceiverConfig(
|
|
447
|
+
endpoint="https://otel.collector.example.com/v1/traces",
|
|
448
|
+
headers={"Authorization": "Bearer tok"},
|
|
449
|
+
),
|
|
450
|
+
)
|
|
451
|
+
print(result.exported_count, result.backend)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Select backend and sampler via environment:
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
export SPANFORGE_OBSERVE_BACKEND=otlp # otlp | datadog | grafana | splunk | elastic | local
|
|
458
|
+
export SPANFORGE_OBSERVE_SAMPLER=trace_id_ratio
|
|
459
|
+
export SPANFORGE_OBSERVE_SAMPLE_RATE=0.25
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### 7. Route alerts with sf-alert (v2.0.6+)
|
|
465
|
+
|
|
466
|
+
Publish topic-based alerts to Slack, PagerDuty, OpsGenie, Teams, SMS, and
|
|
467
|
+
custom webhooks — with built-in deduplication, escalation policy, and
|
|
468
|
+
maintenance-window suppression:
|
|
469
|
+
|
|
470
|
+
```python
|
|
471
|
+
from spanforge.sdk import sf_alert
|
|
472
|
+
|
|
473
|
+
# Publish a CRITICAL drift alert
|
|
474
|
+
result = sf_alert.publish(
|
|
475
|
+
"halluccheck.drift.red",
|
|
476
|
+
{"model": "gpt-4o", "drift_score": 0.91},
|
|
477
|
+
severity="critical",
|
|
478
|
+
project_id="my-agent",
|
|
479
|
+
)
|
|
480
|
+
print(result.alert_id) # UUID4
|
|
481
|
+
print(result.suppressed) # True if deduplicated / maintenance window
|
|
482
|
+
|
|
483
|
+
# Acknowledge to cancel the 15-minute escalation timer
|
|
484
|
+
sf_alert.acknowledge(result.alert_id)
|
|
485
|
+
|
|
486
|
+
# Register a custom topic
|
|
487
|
+
sf_alert.register_topic(
|
|
488
|
+
"myapp.pipeline.failed",
|
|
489
|
+
"ML pipeline execution failure",
|
|
490
|
+
"high",
|
|
491
|
+
runbook_url="https://runbooks.example.com/pipeline",
|
|
492
|
+
)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Configure sinks via environment variables (zero code required):
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
export SPANFORGE_ALERT_TEAMS_WEBHOOK=https://xxx.webhook.office.com/...
|
|
499
|
+
export SPANFORGE_ALERT_OPSGENIE_KEY=og-key-...
|
|
500
|
+
export SPANFORGE_ALERT_DEDUP_SECONDS=300
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
### 8. Enforce release gates with sf-gate (v2.0.7+)
|
|
506
|
+
|
|
507
|
+
Run YAML-declared quality gates before every release. Block on schema violations,
|
|
508
|
+
secrets leaks, performance regressions, unsafe PRRI scores, and trust failures
|
|
509
|
+
— all in a single pipeline command:
|
|
510
|
+
|
|
511
|
+
```python
|
|
512
|
+
from spanforge.sdk import sf_gate
|
|
513
|
+
|
|
514
|
+
# Run a full YAML gate pipeline — blocks on any FAIL gate
|
|
515
|
+
result = sf_gate.run_pipeline("gates/ci-pipeline.yaml")
|
|
516
|
+
for g in result.gate_results:
|
|
517
|
+
print(f"[{g.verdict.value}] {g.gate_id}") # e.g. [PASS] schema-validation
|
|
518
|
+
|
|
519
|
+
# Evaluate a single gate programmatically
|
|
520
|
+
verdict = sf_gate.evaluate("schema-validation", event.to_dict())
|
|
521
|
+
print(verdict.verdict) # GateVerdict.PASS
|
|
522
|
+
|
|
523
|
+
# Standalone PRRI evaluation
|
|
524
|
+
prri = sf_gate.evaluate_prri(prri_score=28.5)
|
|
525
|
+
print(prri.verdict) # PRRIVerdict.GREEN
|
|
526
|
+
|
|
527
|
+
# Composite trust gate — checks HRI rate, PII, and secrets windows
|
|
528
|
+
trust = sf_gate.get_status()
|
|
529
|
+
print(trust.healthy) # True if all thresholds are within bounds
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Or from CI directly:
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
# Runs the pipeline, exits 1 if any blocking gate fails
|
|
536
|
+
spanforge gate run gates/ci-pipeline.yaml
|
|
537
|
+
|
|
538
|
+
# Enforce the composite trust gate as a deployment prerequisite
|
|
539
|
+
spanforge gate trust-gate --project-id my-agent
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
A minimal `ci-pipeline.yaml`:
|
|
543
|
+
|
|
544
|
+
```yaml
|
|
545
|
+
version: "1.0"
|
|
546
|
+
gates:
|
|
547
|
+
- id: schema-validation
|
|
548
|
+
type: schema_validation
|
|
549
|
+
on_fail: block
|
|
550
|
+
- id: secrets-scan
|
|
551
|
+
type: secrets_scan
|
|
552
|
+
on_fail: block
|
|
553
|
+
- id: prri-check
|
|
554
|
+
type: halluccheck_prri
|
|
555
|
+
params:
|
|
556
|
+
red_threshold: 65
|
|
557
|
+
on_fail: block
|
|
558
|
+
- id: trust-gate
|
|
559
|
+
type: halluccheck_trust
|
|
560
|
+
on_fail: block
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
### 9. Unified config & local fallback (v2.0.8+)
|
|
566
|
+
|
|
567
|
+
Bootstrap all 8 services from a single `.halluccheck.toml` config block.
|
|
568
|
+
When a remote service is unreachable, the SDK automatically falls back to
|
|
569
|
+
a local-mode equivalent — no code changes required:
|
|
570
|
+
|
|
571
|
+
```toml
|
|
572
|
+
# .halluccheck.toml
|
|
573
|
+
[spanforge]
|
|
574
|
+
enabled = true
|
|
575
|
+
project_id = "my-agent"
|
|
576
|
+
endpoint = "https://api.spanforge.example.com"
|
|
577
|
+
|
|
578
|
+
[spanforge.services]
|
|
579
|
+
sf_pii = true
|
|
580
|
+
sf_secrets = true
|
|
581
|
+
sf_audit = true
|
|
582
|
+
sf_observe = true
|
|
583
|
+
|
|
584
|
+
[spanforge.local_fallback]
|
|
585
|
+
enabled = true
|
|
586
|
+
max_retries = 3
|
|
587
|
+
timeout_ms = 2000
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
```python
|
|
591
|
+
from spanforge.sdk import load_config_file, validate_config
|
|
592
|
+
|
|
593
|
+
# Parse, validate, and apply env-var overrides in one call
|
|
594
|
+
config = load_config_file() # auto-discovers .halluccheck.toml
|
|
595
|
+
errors = validate_config(config) # [] when valid
|
|
596
|
+
print(config.services.sf_pii) # True
|
|
597
|
+
print(config.local_fallback.timeout_ms) # 2000
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
Validate from the CLI:
|
|
601
|
+
|
|
602
|
+
```bash
|
|
603
|
+
spanforge config validate # auto-discover
|
|
604
|
+
spanforge config validate --file .halluccheck.toml # explicit path
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
When a service is down, fallback activates automatically:
|
|
608
|
+
|
|
609
|
+
```python
|
|
610
|
+
from spanforge.sdk import pii_fallback, secrets_fallback, audit_fallback
|
|
611
|
+
|
|
612
|
+
# Local regex PII scan (no remote service required)
|
|
613
|
+
result = pii_fallback("Contact alice@example.com")
|
|
614
|
+
print(result["entities"]) # [{"type": "EMAIL", ...}]
|
|
615
|
+
|
|
616
|
+
# Local secrets scan
|
|
617
|
+
result = secrets_fallback("AKIA1234567890ABCDEF")
|
|
618
|
+
print(result["clean"]) # False
|
|
619
|
+
|
|
620
|
+
# Local HMAC-chained JSONL audit
|
|
621
|
+
audit_fallback(
|
|
622
|
+
{"score": 0.92, "model": "gpt-4o"},
|
|
623
|
+
schema_key="halluccheck.score.v1",
|
|
624
|
+
)
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
The `ServiceRegistry` tracks health for all services and re-checks every 60 s:
|
|
628
|
+
|
|
629
|
+
```python
|
|
630
|
+
from spanforge.sdk import ServiceRegistry
|
|
631
|
+
|
|
632
|
+
reg = ServiceRegistry.get_instance()
|
|
633
|
+
status = reg.status_response()
|
|
634
|
+
# {"sf_pii": {"status": "up", "latency_ms": 45, "last_checked_at": "..."}, ...}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
### 10. T.R.U.S.T. Scorecard & HallucCheck pipelines (v2.0.9+)
|
|
640
|
+
|
|
641
|
+
The T.R.U.S.T. scorecard aggregates five trust dimensions into a single weighted score with colour-band verdicts. Each pillar maps to existing audit telemetry:
|
|
642
|
+
|
|
643
|
+
| Pillar | What it measures | Source |
|
|
644
|
+
|--------|-----------------|--------|
|
|
645
|
+
| **T**ransparency | Gate pass rate | `sf_gate` evaluations |
|
|
646
|
+
| **R**eliability | Hallucination rate | `halluccheck.score.v1` records |
|
|
647
|
+
| **U**serTrust | Bias disparity | `halluccheck.bias.v1` records |
|
|
648
|
+
| **S**ecurity | PII + secrets hygiene | `sf_pii` / `sf_secrets` scans |
|
|
649
|
+
| **T**raceability | Compliance posture | Attestation coverage |
|
|
650
|
+
|
|
651
|
+
Colour bands: **green** ≥ 80, **amber** ≥ 60, **red** < 60.
|
|
652
|
+
|
|
653
|
+
```python
|
|
654
|
+
from spanforge.sdk import sf_trust
|
|
655
|
+
|
|
656
|
+
# Full scorecard with all five dimensions
|
|
657
|
+
scorecard = sf_trust.get_scorecard(project_id="my-agent")
|
|
658
|
+
print(scorecard.overall_score) # 82.5
|
|
659
|
+
print(scorecard.colour_band) # "green"
|
|
660
|
+
print(scorecard.reliability) # TrustDimension(score=90.0, trend="up", ...)
|
|
661
|
+
|
|
662
|
+
# SVG badge for dashboards / README shields
|
|
663
|
+
badge = sf_trust.get_badge(project_id="my-agent")
|
|
664
|
+
with open("trust-badge.svg", "w") as f:
|
|
665
|
+
f.write(badge.svg)
|
|
666
|
+
|
|
667
|
+
# Historical time-series (10 buckets)
|
|
668
|
+
history = sf_trust.get_history(project_id="my-agent", buckets=10)
|
|
669
|
+
for entry in history:
|
|
670
|
+
print(entry.timestamp, entry.overall)
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
Five HallucCheck pipeline integrations orchestrate cross-service workflows:
|
|
674
|
+
|
|
675
|
+
```python
|
|
676
|
+
from spanforge.sdk.pipelines import (
|
|
677
|
+
score_pipeline,
|
|
678
|
+
bias_pipeline,
|
|
679
|
+
monitor_pipeline,
|
|
680
|
+
risk_pipeline,
|
|
681
|
+
benchmark_pipeline,
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
# Score pipeline: PII scan → secrets scan → observe span → audit append
|
|
685
|
+
result = score_pipeline("The model output to check", model="gpt-4o")
|
|
686
|
+
print(result.audit_id, result.details)
|
|
687
|
+
|
|
688
|
+
# Risk pipeline: PRRI evaluation → alert if RED → gate block → CEC bundle
|
|
689
|
+
result = risk_pipeline(prri_score=75.0, project_id="my-agent")
|
|
690
|
+
print(result.details["verdict"]) # "RED"
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
From the CLI:
|
|
694
|
+
|
|
695
|
+
```bash
|
|
696
|
+
# T.R.U.S.T. scorecard (text table)
|
|
697
|
+
spanforge trust scorecard --project-id my-agent
|
|
698
|
+
|
|
699
|
+
# SVG badge to stdout
|
|
700
|
+
spanforge trust badge --project-id my-agent > trust.svg
|
|
701
|
+
|
|
702
|
+
# Composite trust gate (exit 1 = trust below threshold)
|
|
703
|
+
spanforge trust gate --project-id my-agent
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
708
|
+
### 11. Test with zero-network mocks (v2.0.11+)
|
|
709
|
+
|
|
710
|
+
Drop-in mock service clients for every SpanForge SDK service — no network,
|
|
711
|
+
no configuration, no side-effects:
|
|
712
|
+
|
|
713
|
+
```python
|
|
714
|
+
from spanforge.testing_mocks import mock_all_services
|
|
715
|
+
|
|
716
|
+
with mock_all_services():
|
|
717
|
+
from spanforge.sdk import sf_pii, sf_audit, sf_gate
|
|
718
|
+
|
|
719
|
+
# All calls are local, recorded, and return sensible defaults
|
|
720
|
+
result = sf_pii.scan_text("Contact alice@example.com")
|
|
721
|
+
assert result.clean # mock returns clean=True by default
|
|
722
|
+
|
|
723
|
+
sf_audit.append({"score": 0.92}, schema_key="halluccheck.score.v1")
|
|
724
|
+
assert len(sf_audit.calls) == 1 # inspect recorded calls
|
|
725
|
+
|
|
726
|
+
prri = sf_gate.evaluate_prri(prri_score=28.5)
|
|
727
|
+
assert prri.allow # GREEN by default
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
Override default returns per-method:
|
|
731
|
+
|
|
732
|
+
```python
|
|
733
|
+
from spanforge.testing_mocks import MockSFPII
|
|
734
|
+
|
|
735
|
+
mock = MockSFPII()
|
|
736
|
+
mock.configure_response("scan_text", {"clean": False, "entities": ["EMAIL"]})
|
|
737
|
+
result = mock.scan_text("test")
|
|
738
|
+
assert not result["clean"]
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
Run `spanforge doctor` for a full environment diagnostic:
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
spanforge doctor
|
|
745
|
+
# ✅ Config valid
|
|
746
|
+
# ✅ All 11 services reachable
|
|
747
|
+
# ✅ API key not expired
|
|
748
|
+
# ✅ PII/secrets patterns loaded
|
|
749
|
+
# ✅ Gate YAML valid
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
## Regulatory framework coverage
|
|
755
|
+
|
|
756
|
+
The `ComplianceMappingEngine` maps your telemetry events to specific regulatory clauses:
|
|
757
|
+
|
|
758
|
+
| Framework | Clause | Mapped events | What it proves |
|
|
759
|
+
|-----------|--------|---------------|----------------|
|
|
760
|
+
| **GDPR** | Art. 22 | `consent.*`, `hitl.*` | Automated decisions have consent + human oversight |
|
|
761
|
+
| **GDPR** | Art. 25 | `llm.redact.*`, `consent.*` | Privacy by design — PII handled before export |
|
|
762
|
+
| **EU AI Act** | Art. 13 | `explanation.*` | AI decisions are transparent and explainable |
|
|
763
|
+
| **EU AI Act** | Art. 14 | `hitl.*`, `consent.*` | Human oversight of high-risk AI |
|
|
764
|
+
| **EU AI Act** | Annex IV.5 | `llm.guard.*`, `llm.audit.*`, `hitl.*` | Technical documentation — safety + oversight |
|
|
765
|
+
| **SOC 2** | CC6.1 | `llm.audit.*`, `llm.trace.*`, `model_registry.*` | Logical access controls + model governance |
|
|
766
|
+
| **NIST AI RMF** | MAP 1.1 | `llm.trace.*`, `llm.eval.*`, `model_registry.*`, `explanation.*` | Risk identification and mapping |
|
|
767
|
+
| **HIPAA** | §164.312 | `llm.redact.*`, `llm.audit.*` | PHI access controls and audit |
|
|
768
|
+
| **ISO 42001** | A.5–A.10 | Full event set | AI management system controls |
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
## Compliance event types
|
|
773
|
+
|
|
774
|
+
spanforge defines purpose-built event types for AI governance — these aren't afterthought log messages, they are first-class compliance primitives:
|
|
775
|
+
|
|
776
|
+
| Category | Event types | Purpose |
|
|
777
|
+
|----------|------------|---------|
|
|
778
|
+
| **Consent** | `consent.granted`, `consent.revoked`, `consent.violation` | Track user consent for automated processing |
|
|
779
|
+
| **Human-in-the-Loop** | `hitl.queued`, `hitl.reviewed`, `hitl.escalated`, `hitl.timeout` | Prove human oversight of AI decisions |
|
|
780
|
+
| **Model Registry** | `model_registry.registered`, `model_registry.deprecated`, `model_registry.retired` | Govern model lifecycle and risk |
|
|
781
|
+
| **Explainability** | `explanation.generated` | Attach explanations to AI decisions |
|
|
782
|
+
| **Guardrails** | `llm.guard.*` | Safety classifier outputs and block decisions |
|
|
783
|
+
| **PII** | `llm.redact.*` | Audit trail of what PII was found and removed |
|
|
784
|
+
| **Audit** | `llm.audit.*` | Access logs and chain-of-custody records |
|
|
785
|
+
| **Traces** | `llm.trace.*` | Model calls, tokens, latency, cost |
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
## Core capabilities
|
|
790
|
+
|
|
791
|
+
### Tamper-proof audit chains
|
|
792
|
+
|
|
793
|
+
Every event is HMAC-SHA256 signed and chained to its predecessor — the same principle as certificate chains. Alter one event and the entire chain breaks.
|
|
794
|
+
|
|
795
|
+
```python
|
|
796
|
+
from spanforge.signing import AuditStream, verify_chain
|
|
797
|
+
|
|
798
|
+
stream = AuditStream(org_secret="your-secret")
|
|
799
|
+
for event in events:
|
|
800
|
+
stream.append(event)
|
|
801
|
+
|
|
802
|
+
result = verify_chain(stream.events, org_secret="your-secret")
|
|
803
|
+
assert result.valid # any tampering → False
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
### PII redaction
|
|
807
|
+
|
|
808
|
+
Strip personal data before events leave your application boundary. Deep scanning with Luhn and Verhoeff validation for credit cards and Aadhaar numbers, SSN range validation (`_is_valid_ssn`), calendar validation for dates of birth (`_is_valid_date`), and built-in patterns for `date_of_birth` and street `address`.
|
|
809
|
+
|
|
810
|
+
```python
|
|
811
|
+
from spanforge.redact import RedactionPolicy, Sensitivity
|
|
812
|
+
|
|
813
|
+
policy = RedactionPolicy(min_sensitivity=Sensitivity.PII, redacted_by="policy:gdpr-v1")
|
|
814
|
+
result = policy.apply(event)
|
|
815
|
+
# All PII fields → "[REDACTED by policy:gdpr-v1]"
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### Model registry governance
|
|
819
|
+
|
|
820
|
+
Register models with ownership and risk metadata. Attestations automatically warn when models are deprecated, retired, or unregistered.
|
|
821
|
+
|
|
822
|
+
```python
|
|
823
|
+
from spanforge.model_registry import ModelRegistry
|
|
824
|
+
|
|
825
|
+
registry = ModelRegistry()
|
|
826
|
+
registry.register("gpt-4o", owner="ml-platform", risk_tier="high")
|
|
827
|
+
registry.deprecate("gpt-3.5-turbo", reason="Successor available")
|
|
828
|
+
|
|
829
|
+
# Evidence packages now include:
|
|
830
|
+
# model_owner: "ml-platform"
|
|
831
|
+
# model_risk_tier: "high"
|
|
832
|
+
# model_status: "active"
|
|
833
|
+
# model_warnings: [] (or ["model 'gpt-3.5-turbo' is deprecated"])
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### Explainability tracking
|
|
837
|
+
|
|
838
|
+
Measure what percentage of your AI decisions have explanations attached:
|
|
839
|
+
|
|
840
|
+
```python
|
|
841
|
+
from spanforge.explain import generate_explanation
|
|
842
|
+
|
|
843
|
+
explanation = generate_explanation(
|
|
844
|
+
decision_event_id="evt_01HX...",
|
|
845
|
+
method="feature_importance",
|
|
846
|
+
content="Top factors: credit_score (0.42), income (0.31)...",
|
|
847
|
+
)
|
|
848
|
+
# explanation_coverage_pct in attestations = explained / total decisions
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
### GDPR subject erasure
|
|
852
|
+
|
|
853
|
+
Right-to-erasure with tombstone events that preserve audit chain integrity:
|
|
854
|
+
|
|
855
|
+
```bash
|
|
856
|
+
spanforge audit erase audit.jsonl --subject-id user123
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
---
|
|
860
|
+
|
|
861
|
+
## Auto-instrumentation
|
|
862
|
+
|
|
863
|
+
Patch supported providers once — compliance data flows automatically:
|
|
864
|
+
|
|
865
|
+
```python
|
|
866
|
+
# Instrument all installed providers in one call
|
|
867
|
+
import spanforge.auto
|
|
868
|
+
spanforge.auto.setup()
|
|
869
|
+
|
|
870
|
+
# Or patch individually
|
|
871
|
+
from spanforge.integrations import openai as sf_openai
|
|
872
|
+
sf_openai.patch() # every OpenAI call → signed, redacted, compliant
|
|
873
|
+
sf_openai.unpatch() # restore original behaviour
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
**Supported providers:** OpenAI, Anthropic, Google Gemini, AWS Bedrock, Ollama, Groq, Together AI
|
|
877
|
+
|
|
878
|
+
**Supported frameworks:** LangChain, LlamaIndex, CrewAI
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## Using SpanForge alongside OpenTelemetry
|
|
883
|
+
|
|
884
|
+
spanforge is not an OTel replacement. OTel handles performance monitoring. spanforge adds the compliance layer OTel cannot provide — audit chains, PII redaction, consent tracking, and regulator-ready attestations.
|
|
885
|
+
|
|
886
|
+
```python
|
|
887
|
+
# Your existing OTel pipeline stays untouched
|
|
888
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
889
|
+
provider = TracerProvider()
|
|
890
|
+
|
|
891
|
+
# Add spanforge's compliance layer alongside it
|
|
892
|
+
import spanforge
|
|
893
|
+
spanforge.configure(mode="otel_passthrough")
|
|
894
|
+
|
|
895
|
+
# Dual-stream: OTel for monitoring, spanforge for compliance
|
|
896
|
+
spanforge.configure(exporters=["otel_passthrough", "jsonl"], endpoint="audit.jsonl")
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## Export
|
|
902
|
+
|
|
903
|
+
Ship compliance events to any backend:
|
|
904
|
+
|
|
905
|
+
```python
|
|
906
|
+
from spanforge.stream import EventStream
|
|
907
|
+
from spanforge.export.jsonl import JSONLExporter
|
|
908
|
+
from spanforge.export.otlp import OTLPExporter
|
|
909
|
+
from spanforge.export.datadog import DatadogExporter
|
|
910
|
+
from spanforge.export.grafana import GrafanaLokiExporter
|
|
911
|
+
from spanforge.export.cloud import CloudExporter
|
|
912
|
+
from spanforge.export.siem_splunk import SplunkHECExporter
|
|
913
|
+
from spanforge.export.siem_syslog import SyslogExporter
|
|
914
|
+
|
|
915
|
+
stream = EventStream(events)
|
|
916
|
+
|
|
917
|
+
await stream.drain(JSONLExporter("audit.jsonl")) # local file
|
|
918
|
+
await stream.drain(OTLPExporter("http://collector:4318/v1/traces")) # OTel collector
|
|
919
|
+
await stream.drain(DatadogExporter(service="my-app")) # Datadog APM
|
|
920
|
+
await stream.drain(GrafanaLokiExporter(url="http://loki:3100")) # Grafana Loki
|
|
921
|
+
await stream.drain(CloudExporter(api_key="sf_live_xxx")) # spanforge Cloud
|
|
922
|
+
await stream.drain(SplunkHECExporter()) # Splunk HEC (env-var config)
|
|
923
|
+
await stream.drain(SyslogExporter()) # Syslog/CEF (env-var config)
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
Fan-out routing for compliance alerting:
|
|
927
|
+
|
|
928
|
+
```python
|
|
929
|
+
from spanforge.export.webhook import WebhookExporter
|
|
930
|
+
|
|
931
|
+
# Route guardrail violations to Slack
|
|
932
|
+
await stream.route(
|
|
933
|
+
WebhookExporter("https://hooks.slack.com/your-webhook"),
|
|
934
|
+
predicate=lambda e: e.event_type == "llm.guard.output.blocked",
|
|
935
|
+
)
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
---
|
|
939
|
+
|
|
940
|
+
## CLI
|
|
941
|
+
|
|
942
|
+
32 commands — all CI-pipeline ready:
|
|
943
|
+
|
|
944
|
+
```bash
|
|
945
|
+
# Compliance
|
|
946
|
+
spanforge compliance generate --model-id gpt-4o --framework eu_ai_act \
|
|
947
|
+
--from 2026-01-01 --to 2026-03-31 --events-file events.jsonl
|
|
948
|
+
spanforge compliance check --framework eu_ai_act \
|
|
949
|
+
--from 2026-01-01 --to 2026-03-31 --events-file events.jsonl
|
|
950
|
+
spanforge compliance validate-attestation evidence.json
|
|
951
|
+
spanforge compliance status --events-file events.jsonl # compliance summary JSON
|
|
952
|
+
|
|
953
|
+
# Audit chain
|
|
954
|
+
spanforge audit-chain events.jsonl # verify chain integrity
|
|
955
|
+
spanforge audit erase events.jsonl --subject-id user123 # GDPR erasure
|
|
956
|
+
spanforge audit rotate-key events.jsonl # key rotation
|
|
957
|
+
spanforge audit verify --input events.jsonl # verify integrity
|
|
958
|
+
|
|
959
|
+
# Privacy & Secrets
|
|
960
|
+
spanforge scan events.jsonl --fail-on-match # CI-gate PII scan
|
|
961
|
+
spanforge secrets scan <file> # scan file for secrets (exit 0=clean, 1=found)
|
|
962
|
+
spanforge secrets scan <file> --format sarif # SARIF output for GitHub Code Scanning
|
|
963
|
+
spanforge secrets scan <file> --redact # print redacted version to stdout
|
|
964
|
+
|
|
965
|
+
# Validation
|
|
966
|
+
spanforge check # end-to-end health check
|
|
967
|
+
spanforge check-compat events.json # v2.0 compatibility
|
|
968
|
+
spanforge validate events.jsonl # JSON Schema validation
|
|
969
|
+
|
|
970
|
+
# Configuration
|
|
971
|
+
spanforge config validate # validate .halluccheck.toml (auto-discover)
|
|
972
|
+
spanforge config validate --file path/to.toml # validate specific config file
|
|
973
|
+
|
|
974
|
+
# Analysis
|
|
975
|
+
spanforge stats events.jsonl # counts, tokens, cost
|
|
976
|
+
spanforge inspect <EVENT_ID> events.jsonl # pretty-print one event
|
|
977
|
+
spanforge cost events.jsonl # token spend report
|
|
978
|
+
spanforge cost run --run-id <id> --input events.jsonl # per-run cost report
|
|
979
|
+
|
|
980
|
+
# Evaluation
|
|
981
|
+
spanforge eval save --input events.jsonl --output dataset.jsonl # extract eval dataset
|
|
982
|
+
spanforge eval run --file dataset.jsonl --scorers faithfulness,pii_leakage # run scorers
|
|
983
|
+
|
|
984
|
+
# Migration
|
|
985
|
+
spanforge migrate events.jsonl --sign # v1→v2 migration
|
|
986
|
+
spanforge migrate-langsmith export.jsonl # LangSmith → SpanForge conversion
|
|
987
|
+
spanforge list-deprecated # deprecated event types
|
|
988
|
+
spanforge migration-roadmap # v2 migration plan
|
|
989
|
+
spanforge check-consumers # consumer compatibility
|
|
990
|
+
|
|
991
|
+
# CI/CD Gate Pipeline
|
|
992
|
+
spanforge gate run gates/ci-pipeline.yaml # run YAML gate pipeline (exit 1 = blocking gate failed)
|
|
993
|
+
spanforge gate run gates/ci-pipeline.yaml --format json # JSON output for CI dashboards
|
|
994
|
+
spanforge gate evaluate schema-validation --payload event.json # evaluate single gate
|
|
995
|
+
spanforge gate trust-gate --project-id my-agent # composite trust gate check
|
|
996
|
+
|
|
997
|
+
# T.R.U.S.T. Scorecard
|
|
998
|
+
spanforge trust scorecard --project-id my-agent # five-pillar trust scorecard (text table)
|
|
999
|
+
spanforge trust badge --project-id my-agent # SVG badge to stdout
|
|
1000
|
+
spanforge trust gate --project-id my-agent # composite trust gate (exit 1 = below threshold)
|
|
1001
|
+
|
|
1002
|
+
# Enterprise (Phase 11)
|
|
1003
|
+
spanforge enterprise status # enterprise subsystem status JSON
|
|
1004
|
+
spanforge enterprise health # enterprise health check (all services)
|
|
1005
|
+
|
|
1006
|
+
# Security (Phase 11)
|
|
1007
|
+
spanforge security owasp # OWASP API Security Top 10 audit
|
|
1008
|
+
spanforge security scan # full security scan (deps + static + secrets-in-logs)
|
|
1009
|
+
spanforge security threat-model # STRIDE threat model summary
|
|
1010
|
+
spanforge security audit-logs --path /var/log/myapp/ # secrets-in-logs detection
|
|
1011
|
+
|
|
1012
|
+
# Developer Experience (Phase 12)
|
|
1013
|
+
spanforge doctor # environment diagnostics (config, services, keys, patterns)
|
|
1014
|
+
|
|
1015
|
+
# Viewer
|
|
1016
|
+
spanforge serve # local SPA trace viewer
|
|
1017
|
+
spanforge ui # standalone HTML viewer
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
## Event namespaces
|
|
1023
|
+
|
|
1024
|
+
Every event carries a typed ``payload``. The built-in namespaces:
|
|
1025
|
+
|
|
1026
|
+
| Prefix | Dataclass | What it records |
|
|
1027
|
+
|---|---|---|
|
|
1028
|
+
| `consent.*` | `ConsentPayload` | User consent grants, revocations, violations |
|
|
1029
|
+
| `hitl.*` | `HITLPayload` | Human-in-the-loop review, escalation, timeout |
|
|
1030
|
+
| `model_registry.*` | `ModelRegistryEntry` | Model registration, deprecation, retirement |
|
|
1031
|
+
| `explanation.*` | `ExplainabilityRecord` | Explainability records for AI decisions |
|
|
1032
|
+
| `llm.trace.*` | `SpanPayload` | Model calls — tokens, latency, cost **(frozen v2)** |
|
|
1033
|
+
| `llm.guard.*` | `GuardPayload` | Safety classifier outputs, block decisions |
|
|
1034
|
+
| `llm.redact.*` | `RedactPayload` | PII audit — what was found and removed |
|
|
1035
|
+
| `llm.audit.*` | `AuditChainPayload` | Access logs and chain-of-custody |
|
|
1036
|
+
| `llm.eval.*` | `EvalScenarioPayload` | Scores, labels, evaluator identity |
|
|
1037
|
+
| `llm.cost.*` | `CostPayload` | Per-call cost in USD |
|
|
1038
|
+
| `llm.cache.*` | `CachePayload` | Cache hit/miss, backend, TTL |
|
|
1039
|
+
| `llm.prompt.*` | `PromptPayload` | Prompt template version, rendered text |
|
|
1040
|
+
| `llm.fence.*` | `FencePayload` | Topic constraints, allow/block lists |
|
|
1041
|
+
| `llm.diff.*` | `DiffPayload` | Prompt/response delta between events |
|
|
1042
|
+
| `llm.template.*` | `TemplatePayload` | Template registry metadata |
|
|
1043
|
+
|
|
1044
|
+
---
|
|
1045
|
+
|
|
1046
|
+
## Architecture
|
|
1047
|
+
|
|
1048
|
+
```
|
|
1049
|
+
spanforge/
|
|
1050
|
+
+-- core/
|
|
1051
|
+
│ +-- compliance_mapping.py — ComplianceMappingEngine, evidence packages, attestations
|
|
1052
|
+
+-- compliance/ — Programmatic compliance test suite
|
|
1053
|
+
+-- signing.py — HMAC audit chains, key management, multi-tenant KeyResolver
|
|
1054
|
+
+-- redact.py — PII detection + redaction policies
|
|
1055
|
+
+-- model_registry.py — Model lifecycle governance
|
|
1056
|
+
+-- explain.py — Explainability records
|
|
1057
|
+
+-- consent.py — Consent boundary events
|
|
1058
|
+
+-- hitl.py — Human-in-the-loop events
|
|
1059
|
+
+-- governance.py — Policy-based event gating
|
|
1060
|
+
+-- event.py — Event envelope
|
|
1061
|
+
+-- types.py — EventType enum (consent.*, hitl.*, model_registry.*, explanation.*, llm.*)
|
|
1062
|
+
+-- config.py — configure() / get_config()
|
|
1063
|
+
+-- _span.py — Span, AgentRun, AgentStep context managers
|
|
1064
|
+
+-- _trace.py — Trace + start_trace()
|
|
1065
|
+
+-- _tracer.py — Top-level tracing entry point
|
|
1066
|
+
+-- _stream.py — Internal dispatch: sample — redact — sign — export
|
|
1067
|
+
+-- _store.py — TraceStore ring buffer
|
|
1068
|
+
+-- _hooks.py — HookRegistry (lifecycle hooks)
|
|
1069
|
+
+-- _server.py — HTTP server (/traces, /compliance/summary)
|
|
1070
|
+
+-- _cli.py ← 25 CLI sub-commands
|
|
1071
|
+
+-- cost.py — CostTracker, BudgetMonitor, @budget_alert
|
|
1072
|
+
+-- cache.py — SemanticCache, @cached decorator
|
|
1073
|
+
+-- retry.py — @retry, FallbackChain, CircuitBreaker
|
|
1074
|
+
+-- toolsmith.py — @tool, ToolRegistry
|
|
1075
|
+
+-- http.py — Zero-dependency OpenAI-compatible HTTP client
|
|
1076
|
+
+-- io.py — JSONL read/write/append utilities
|
|
1077
|
+
+-- plugins.py — Entry-point plugin discovery
|
|
1078
|
+
+-- schema.py — Lightweight zero-dependency JSON Schema validator
|
|
1079
|
+
+-- regression.py — Pass/fail regression detector
|
|
1080
|
+
+-- stats.py — Percentile, latency summary utilities
|
|
1081
|
+
+-- presidio_backend.py — Optional Presidio-powered PII detection
|
|
1082
|
+
+-- _ansi.py — ANSI color helpers (NO_COLOR aware)
|
|
1083
|
+
+-- lint/ — AST-based instrumentation linter (AO000–AO005)
|
|
1084
|
+
+-- export/ — JSONL, OTLP, Webhook, Datadog, Grafana Loki, Cloud, Redis, Splunk HEC, Syslog/CEF
|
|
1085
|
+
+-- integrations/ — OpenAI, Anthropic, Gemini, Bedrock, LangChain, LlamaIndex, CrewAI, Ollama, Groq, Together
|
|
1086
|
+
+-- namespaces/ — Typed payload dataclasses
|
|
1087
|
+
+-- gate.py — GateRunner YAML pipeline engine, 6 gate executors, artifact store (Phase 8)
|
|
1088
|
+
+-- sdk/ — Service SDK clients (sf-identity, sf-pii, sf-secrets, sf-audit, sf-cec, sf-observe, sf-alert, sf-gate, sf-trust, sf-enterprise, sf-security)
|
|
1089
|
+
│ +-- identity.py — SFIdentityClient – keys, JWT, TOTP, MFA, magic-link
|
|
1090
|
+
│ +-- pii.py — SFPIIClient – scan, redact, anonymize
|
|
1091
|
+
│ +-- secrets.py — SFSecretsClient – 20-pattern secret scanning, SARIF output
|
|
1092
|
+
│ +-- audit.py — SFAuditClient – HMAC-chained records, T.R.U.S.T. scorecard, Article 30, BYOS
|
|
1093
|
+
│ +-- cec.py — SFCECClient – signed CEC ZIP bundles, clause mapping, DPA generation (Phase 5)
|
|
1094
|
+
│ +-- observe.py — SFObserveClient – span export, OTel GenAI attrs, W3C TraceContext, sampling (Phase 6)
|
|
1095
|
+
│ +-- alert.py — SFAlertClient – topic-based routing, dedup, escalation policy, 6 sink integrations (Phase 7)
|
|
1096
|
+
│ +-- gate.py — SFGateClient – YAML pipeline runner, evaluate(), evaluate_prri(), trust-gate, artifact management (Phase 8)
|
|
1097
|
+
│ +-- config.py — .halluccheck.toml parser, SFConfigBlock, SFServiceToggles, SFLocalFallbackConfig, validate_config() (Phase 9)
|
|
1098
|
+
│ +-- registry.py — ServiceRegistry singleton, health checks, background checker, status_response() (Phase 9)
|
|
1099
|
+
│ +-- fallback.py — 8 local fallback implementations: pii, secrets, audit, observe, alert, identity, gate, cec (Phase 9)
|
|
1100
|
+
│ +-- trust.py — SFTrustClient – T.R.U.S.T. five-pillar scorecard, SVG badge, history time-series, configurable weights (Phase 10)
|
|
1101
|
+
│ +-- pipelines.py — 5 HallucCheck pipeline integrations: score, bias, monitor, risk, benchmark (Phase 10)
|
|
1102
|
+
│ +-- enterprise.py — SFEnterpriseClient – multi-tenancy, encryption, air-gap, health probes (Phase 11)
|
|
1103
|
+
│ +-- security.py — SFSecurityClient – OWASP audit, STRIDE threat model, dependency/static scanning, secrets-in-logs (Phase 11)
|
|
1104
|
+
│ +-- testing_mocks.py — 11 mock service clients, _MockBase, mock_all_services() context manager (Phase 12)
|
|
1105
|
+
│ +-- _base.py — SFClientConfig, SFServiceClient, circuit breaker, sandbox mode (Phase 12)
|
|
1106
|
+
│ +-- _types.py — SecretStr, APIKeyBundle, JWTClaims, BundleResult, ClauseMapEntry, ExportResult, Annotation, AlertSeverity, …
|
|
1107
|
+
│ +-- _exceptions.py — SFError hierarchy (incl. SFConfigError, SFConfigValidationError, SFStartupError, SFServiceUnavailableError, SFTrustComputeError, SFPipelineError)
|
|
1108
|
+
│ +-- __init__.py — sf_identity / sf_pii / sf_secrets / sf_audit / sf_cec / sf_observe / sf_alert / sf_gate / sf_trust / sf_enterprise / sf_security / sf_rag / sf_feedback singletons + configure()
|
|
1109
|
+
+-- migrate.py — Schema migration (v1 — v2), LangSmith migration
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
---
|
|
1113
|
+
|
|
1114
|
+
## What is inside the box
|
|
1115
|
+
|
|
1116
|
+
<table>
|
|
1117
|
+
<thead>
|
|
1118
|
+
<tr><th>Module</th><th>What it does</th><th>For whom</th></tr>
|
|
1119
|
+
</thead>
|
|
1120
|
+
<tbody>
|
|
1121
|
+
<tr>
|
|
1122
|
+
<td><strong>Compliance & Governance</strong></td><td colspan="2"></td>
|
|
1123
|
+
</tr>
|
|
1124
|
+
<tr>
|
|
1125
|
+
<td><code>spanforge.compliance</code></td>
|
|
1126
|
+
<td><code>ComplianceMappingEngine</code> maps telemetry to regulatory frameworks (EU AI Act, ISO 42001, NIST AI RMF, GDPR, SOC 2, HIPAA). Generates evidence packages with HMAC-signed attestations. Consent, HITL, model registry, and explainability events integrated into clause mappings. Attestations include model owner, risk tier, status, warnings, and <code>explanation_coverage_pct</code>. Also: programmatic v2.0 compatibility checks — no pytest required.</td>
|
|
1127
|
+
<td>Compliance / legal / platform teams</td>
|
|
1128
|
+
</tr>
|
|
1129
|
+
<tr>
|
|
1130
|
+
<td><code>spanforge.signing</code></td>
|
|
1131
|
+
<td>HMAC-SHA256 event signing, tamper-evident audit chains, key strength validation, key expiry checks, environment-isolated key derivation, multi-tenant <code>KeyResolver</code> protocol, and <code>AsyncAuditStream</code></td>
|
|
1132
|
+
<td>Security / compliance teams</td>
|
|
1133
|
+
</tr>
|
|
1134
|
+
<tr>
|
|
1135
|
+
<td><code>spanforge.redact</code></td>
|
|
1136
|
+
<td>PII detection, sensitivity levels, redaction policies, deep <code>scan_payload()</code> with Luhn / Verhoeff / SSN-range / date-calendar validation, built-in <code>date_of_birth</code> and <code>address</code> patterns, and <code>contains_pii()</code> / <code>assert_redacted()</code> with raw string scanning</td>
|
|
1137
|
+
<td>Data privacy / GDPR teams</td>
|
|
1138
|
+
</tr>
|
|
1139
|
+
<tr>
|
|
1140
|
+
<td><code>spanforge.secrets</code></td>
|
|
1141
|
+
<td><code>SecretsScanner</code> — 20-pattern registry (7 spec-defined + 13 industry-standard), Shannon entropy scoring, three-tier confidence model, zero-tolerance auto-block for 10 high-risk types, <code>SecretsScanResult</code> with <code>to_dict()</code> and SARIF 2.1.0 output, span deduplication, configurable allowlist</td>
|
|
1142
|
+
<td>Security / DevSecOps teams</td>
|
|
1143
|
+
</tr>
|
|
1144
|
+
<tr>
|
|
1145
|
+
<td><code>spanforge.governance</code></td>
|
|
1146
|
+
<td>Policy-based event gating — block prohibited types, warn on deprecated usage, enforce custom rules</td>
|
|
1147
|
+
<td>Platform / compliance teams</td>
|
|
1148
|
+
</tr>
|
|
1149
|
+
<tr>
|
|
1150
|
+
<td><strong>Instrumentation & Tracing</strong></td><td colspan="2"></td>
|
|
1151
|
+
</tr>
|
|
1152
|
+
<tr>
|
|
1153
|
+
<td><code>spanforge.event</code></td>
|
|
1154
|
+
<td>The core <code>Event</code> envelope — the one structure all tools share</td>
|
|
1155
|
+
<td>Everyone</td>
|
|
1156
|
+
</tr>
|
|
1157
|
+
<tr>
|
|
1158
|
+
<td><code>spanforge.types</code></td>
|
|
1159
|
+
<td>All built-in event types — compliance events (<code>consent.*</code>, <code>hitl.*</code>, <code>model_registry.*</code>, <code>explanation.*</code>) and telemetry events (<code>llm.trace.*</code>, <code>llm.guard.*</code>, etc.)</td>
|
|
1160
|
+
<td>Everyone</td>
|
|
1161
|
+
</tr>
|
|
1162
|
+
<tr>
|
|
1163
|
+
<td><code>spanforge._span</code></td>
|
|
1164
|
+
<td>Span, AgentRun, AgentStep context managers. <code>contextvars</code>-based async/thread-safe propagation. <code>async with</code>, <code>span.add_event()</code>, <code>span.set_timeout_deadline()</code></td>
|
|
1165
|
+
<td>App developers</td>
|
|
1166
|
+
</tr>
|
|
1167
|
+
<tr>
|
|
1168
|
+
<td><code>spanforge._trace</code></td>
|
|
1169
|
+
<td><code>Trace</code> + <code>start_trace()</code> — high-level tracing entry point; accumulates child spans</td>
|
|
1170
|
+
<td>App developers</td>
|
|
1171
|
+
</tr>
|
|
1172
|
+
<tr>
|
|
1173
|
+
<td><code>spanforge.config</code></td>
|
|
1174
|
+
<td><code>configure()</code> and <code>get_config()</code> — signing key, redaction policy, exporters, sample rate</td>
|
|
1175
|
+
<td>Everyone</td>
|
|
1176
|
+
</tr>
|
|
1177
|
+
<tr>
|
|
1178
|
+
<td><strong>Export & Integration</strong></td><td colspan="2"></td>
|
|
1179
|
+
</tr>
|
|
1180
|
+
<tr>
|
|
1181
|
+
<td><code>spanforge.export</code></td>
|
|
1182
|
+
<td>Ship events to JSONL, HTTP webhooks, OTLP collectors, Datadog APM, Grafana Loki, Splunk HEC, Syslog/CEF, Redis, or spanforge Cloud</td>
|
|
1183
|
+
<td>Infra / compliance teams</td>
|
|
1184
|
+
</tr>
|
|
1185
|
+
<tr>
|
|
1186
|
+
<td><code>spanforge.export.siem_splunk</code></td>
|
|
1187
|
+
<td><code>SplunkHECExporter</code> — thread-safe batched Splunk HTTP Event Collector exporter; env-var config; HEC token never logged; <code>SplunkHECError</code> on delivery failure</td>
|
|
1188
|
+
<td>Security / compliance teams</td>
|
|
1189
|
+
</tr>
|
|
1190
|
+
<tr>
|
|
1191
|
+
<td><code>spanforge.export.siem_syslog</code></td>
|
|
1192
|
+
<td><code>SyslogExporter</code> — RFC 5424 and ArcSight CEF exporter over UDP or TCP; severity derived from event type; CEF extension values properly escaped; <code>SyslogExporterError</code> on socket failure</td>
|
|
1193
|
+
<td>Security / compliance teams</td>
|
|
1194
|
+
</tr>
|
|
1195
|
+
<tr>
|
|
1196
|
+
<td><code>spanforge.stream</code></td>
|
|
1197
|
+
<td>Fan-out router — one <code>drain()</code> call reaches multiple backends; Kafka source</td>
|
|
1198
|
+
<td>Platform engineers</td>
|
|
1199
|
+
</tr>
|
|
1200
|
+
<tr>
|
|
1201
|
+
<td><code>spanforge.integrations</code></td>
|
|
1202
|
+
<td>Auto-instrumentation for OpenAI, Anthropic, LangChain, LlamaIndex, CrewAI, Groq, Ollama, Together</td>
|
|
1203
|
+
<td>App developers</td>
|
|
1204
|
+
</tr>
|
|
1205
|
+
<tr>
|
|
1206
|
+
<td><code>spanforge.auto</code></td>
|
|
1207
|
+
<td><code>setup()</code> auto-patches all installed LLM integrations; <code>teardown()</code> cleanly unpatches</td>
|
|
1208
|
+
<td>App developers</td>
|
|
1209
|
+
</tr>
|
|
1210
|
+
<tr>
|
|
1211
|
+
<td><strong>Developer Tools</strong></td><td colspan="2"></td>
|
|
1212
|
+
</tr>
|
|
1213
|
+
<tr>
|
|
1214
|
+
<td><code>spanforge.cost</code></td>
|
|
1215
|
+
<td><code>CostTracker</code>, <code>BudgetMonitor</code>, <code>@budget_alert</code> — track and alert on token spend</td>
|
|
1216
|
+
<td>App developers / FinOps</td>
|
|
1217
|
+
</tr>
|
|
1218
|
+
<tr>
|
|
1219
|
+
<td><code>spanforge.cache</code></td>
|
|
1220
|
+
<td><code>SemanticCache</code> + <code>@cached</code> — deduplicate LLM calls via cosine similarity; <code>InMemoryBackend</code>, <code>SQLiteBackend</code>, <code>RedisBackend</code></td>
|
|
1221
|
+
<td>App developers / FinOps</td>
|
|
1222
|
+
</tr>
|
|
1223
|
+
<tr>
|
|
1224
|
+
<td><code>spanforge.retry</code></td>
|
|
1225
|
+
<td><code>@retry</code>, <code>FallbackChain</code>, <code>CircuitBreaker</code>, <code>CostAwareRouter</code> — resilient LLM routing with compliance events</td>
|
|
1226
|
+
<td>App developers / SREs</td>
|
|
1227
|
+
</tr>
|
|
1228
|
+
<tr>
|
|
1229
|
+
<td><code>spanforge.toolsmith</code></td>
|
|
1230
|
+
<td><code>@tool</code> + <code>ToolRegistry</code> — register functions as typed tools; render JSON schemas for function-calling APIs</td>
|
|
1231
|
+
<td>App developers</td>
|
|
1232
|
+
</tr>
|
|
1233
|
+
<tr>
|
|
1234
|
+
<td><code>spanforge.lint</code></td>
|
|
1235
|
+
<td>AST-based instrumentation linter; AO001–AO005 codes; flake8 plugin; CLI</td>
|
|
1236
|
+
<td>All teams / CI</td>
|
|
1237
|
+
</tr>
|
|
1238
|
+
<tr>
|
|
1239
|
+
<td><strong>Utilities (v2.0.2+)</strong></td><td colspan="2"></td>
|
|
1240
|
+
</tr>
|
|
1241
|
+
<tr>
|
|
1242
|
+
<td><code>spanforge.http</code></td>
|
|
1243
|
+
<td><code>chat_completion()</code> — zero-dependency, synchronous OpenAI-compatible HTTP client with retry and back-off</td>
|
|
1244
|
+
<td>App developers</td>
|
|
1245
|
+
</tr>
|
|
1246
|
+
<tr>
|
|
1247
|
+
<td><code>spanforge.io</code></td>
|
|
1248
|
+
<td><code>read_jsonl()</code>, <code>write_jsonl()</code>, <code>append_jsonl()</code>, <code>write_events()</code>, <code>read_events()</code> — JSONL I/O utilities</td>
|
|
1249
|
+
<td>Everyone</td>
|
|
1250
|
+
</tr>
|
|
1251
|
+
<tr>
|
|
1252
|
+
<td><code>spanforge.schema</code></td>
|
|
1253
|
+
<td>Lightweight zero-dependency JSON Schema validator — <code>validate()</code>, <code>validate_strict()</code></td>
|
|
1254
|
+
<td>Tool authors / CI</td>
|
|
1255
|
+
</tr>
|
|
1256
|
+
<tr>
|
|
1257
|
+
<td><code>spanforge.regression</code></td>
|
|
1258
|
+
<td><code>RegressionDetector</code> — per-case pass/fail regression detection between baseline and current eval runs</td>
|
|
1259
|
+
<td>ML / eval teams</td>
|
|
1260
|
+
</tr>
|
|
1261
|
+
<tr>
|
|
1262
|
+
<td><code>spanforge.stats</code></td>
|
|
1263
|
+
<td><code>percentile()</code>, <code>latency_summary()</code> — statistical utilities for eval and performance analysis</td>
|
|
1264
|
+
<td>Analytics engineers</td>
|
|
1265
|
+
</tr>
|
|
1266
|
+
<tr>
|
|
1267
|
+
<td><code>spanforge.plugins</code></td>
|
|
1268
|
+
<td><code>discover(group)</code> — entry-point plugin discovery across Python 3.9–3.12+</td>
|
|
1269
|
+
<td>Plugin authors</td>
|
|
1270
|
+
</tr>
|
|
1271
|
+
<tr>
|
|
1272
|
+
<td><code>spanforge.presidio_backend</code></td>
|
|
1273
|
+
<td>Optional Presidio-powered PII detection backend — <code>presidio_scan_payload()</code> with standard <code>PIIScanResult</code></td>
|
|
1274
|
+
<td>Data privacy teams</td>
|
|
1275
|
+
</tr>
|
|
1276
|
+
<tr>
|
|
1277
|
+
<td><code>spanforge.eval</code></td>
|
|
1278
|
+
<td>Built-in scorers: <code>FaithfulnessScorer</code>, <code>RefusalDetectionScorer</code>, <code>PIILeakageScorer</code>, <code>BehaviourScorer</code> base class</td>
|
|
1279
|
+
<td>ML / eval teams</td>
|
|
1280
|
+
</tr>
|
|
1281
|
+
<tr>
|
|
1282
|
+
<td><code>spanforge.debug</code></td>
|
|
1283
|
+
<td><code>print_tree()</code>, <code>summary()</code>, <code>visualize()</code> — terminal tree, stats dict, HTML Gantt timeline</td>
|
|
1284
|
+
<td>App developers</td>
|
|
1285
|
+
</tr>
|
|
1286
|
+
<tr>
|
|
1287
|
+
<td><code>spanforge.metrics</code></td>
|
|
1288
|
+
<td><code>aggregate()</code> — success rates, latency percentiles, token totals, cost breakdowns</td>
|
|
1289
|
+
<td>Analytics engineers</td>
|
|
1290
|
+
</tr>
|
|
1291
|
+
<tr>
|
|
1292
|
+
<td><code>spanforge.testing</code></td>
|
|
1293
|
+
<td><code>MockExporter</code>, <code>capture_events()</code>, <code>assert_event_schema_valid()</code>, <code>trace_store()</code></td>
|
|
1294
|
+
<td>Test authors</td>
|
|
1295
|
+
</tr>
|
|
1296
|
+
<tr>
|
|
1297
|
+
<td><code>spanforge.testing_mocks</code></td>
|
|
1298
|
+
<td>11 drop-in mock service clients (<code>MockSFIdentity</code>, <code>MockSFPII</code>, <code>MockSFSecrets</code>, <code>MockSFAudit</code>, <code>MockSFObserve</code>, <code>MockSFGate</code>, <code>MockSFCEC</code>, <code>MockSFAlert</code>, <code>MockSFTrust</code>, <code>MockSFEnterprise</code>, <code>MockSFSecurity</code>). <code>mock_all_services()</code> context manager patches all 11 singletons. <code>_MockBase</code> with <code>.calls</code> recording and <code>.configure_response()</code>. 100% test coverage. <em>(Phase 12, v2.0.11+)</em></td>
|
|
1299
|
+
<td>Test authors / all teams</td>
|
|
1300
|
+
</tr>
|
|
1301
|
+
<tr>
|
|
1302
|
+
<td><code>spanforge.validate</code></td>
|
|
1303
|
+
<td>JSON Schema validation against the published v2.0 schema</td>
|
|
1304
|
+
<td>All teams</td>
|
|
1305
|
+
</tr>
|
|
1306
|
+
<tr>
|
|
1307
|
+
<td><code>spanforge.namespaces</code></td>
|
|
1308
|
+
<td>Typed payload dataclasses for all built-in event namespaces</td>
|
|
1309
|
+
<td>Tool authors</td>
|
|
1310
|
+
</tr>
|
|
1311
|
+
<tr>
|
|
1312
|
+
<td><code>spanforge.models</code></td>
|
|
1313
|
+
<td>Optional Pydantic v2 models for validated schemas</td>
|
|
1314
|
+
<td>API / backend teams</td>
|
|
1315
|
+
</tr>
|
|
1316
|
+
<tr>
|
|
1317
|
+
<td><code>spanforge.consumer</code></td>
|
|
1318
|
+
<td>Declare schema-namespace dependencies; fail fast at startup if version requirements are not met</td>
|
|
1319
|
+
<td>Platform teams</td>
|
|
1320
|
+
</tr>
|
|
1321
|
+
<tr>
|
|
1322
|
+
<td><code>spanforge.deprecations</code></td>
|
|
1323
|
+
<td>Per-event-type deprecation notices at runtime</td>
|
|
1324
|
+
<td>Library maintainers</td>
|
|
1325
|
+
</tr>
|
|
1326
|
+
<tr>
|
|
1327
|
+
<td><code>spanforge._hooks</code></td>
|
|
1328
|
+
<td>Lifecycle hooks: <code>@hooks.on_llm_call</code>, <code>@hooks.on_tool_call</code>, <code>@hooks.on_agent_start</code> (sync + async)</td>
|
|
1329
|
+
<td>App developers / platform</td>
|
|
1330
|
+
</tr>
|
|
1331
|
+
<tr>
|
|
1332
|
+
<td><code>spanforge._store</code></td>
|
|
1333
|
+
<td><code>TraceStore</code> ring buffer — <code>get_trace()</code>, <code>list_tool_calls()</code>, <code>list_llm_calls()</code></td>
|
|
1334
|
+
<td>Platform / tooling engineers</td>
|
|
1335
|
+
</tr>
|
|
1336
|
+
<tr>
|
|
1337
|
+
<td><code>spanforge._cli</code></td>
|
|
1338
|
+
<td>CLI sub-commands including eval, compliance status, migrate-langsmith, cost run, and more</td>
|
|
1339
|
+
<td>DevOps / CI teams</td>
|
|
1340
|
+
</tr>
|
|
1341
|
+
<tr>
|
|
1342
|
+
<td><strong>Service SDK (v2.0.3+)</strong></td><td colspan="2"></td>
|
|
1343
|
+
</tr>
|
|
1344
|
+
<tr>
|
|
1345
|
+
<td><code>spanforge.sdk.identity</code></td>
|
|
1346
|
+
<td><code>SFIdentityClient</code> — API key lifecycle (<code>issue_api_key</code>, <code>rotate_api_key</code>, <code>revoke_api_key</code>), session JWT (HS256 stdlib / RS256 remote), magic-link issuance + single-use exchange, TOTP enrolment + verification (RFC 6238, 6-digit, 30 s), backup codes, per-key IP allowlist, sliding-window rate limiting, brute-force lockout. Fully local-mode capable — no external service required.</td>
|
|
1347
|
+
<td>Security / platform teams</td>
|
|
1348
|
+
</tr>
|
|
1349
|
+
<tr>
|
|
1350
|
+
<td><code>spanforge.sdk.pii</code></td>
|
|
1351
|
+
<td><code>SFPIIClient</code> — <code>scan_text()</code>, <code>anonymise()</code>, <code>scan_batch()</code>, <code>apply_pipeline_action()</code>, <code>get_status()</code>, <code>erase_subject()</code> (GDPR Art. 17), <code>export_subject_data()</code> (CCPA DSAR), <code>safe_harbor_deidentify()</code> (HIPAA 18-PHI), <code>audit_training_data()</code> (EU AI Act Art. 10), <code>get_pii_stats()</code>. PIPL patterns for Chinese national ID / mobile / bank card. Pipeline action routing (<code>flag</code> / <code>redact</code> / <code>block</code>) with confidence threshold gate. Scan results never include raw PII — only type labels, field paths, and SHA-256 hashes. Runs locally or delegates to a remote sf-pii service.</td>
|
|
1352
|
+
<td>Data privacy / GDPR teams</td>
|
|
1353
|
+
</tr>
|
|
1354
|
+
<tr>
|
|
1355
|
+
<td><code>spanforge.sdk.secrets</code></td>
|
|
1356
|
+
<td><code>SFSecretsClient</code> — <code>scan(text)</code> → <code>SecretsScanResult</code>, <code>scan_batch(texts)</code> with asyncio parallel execution. 20-pattern registry covering all spec-required types plus 13 industry-standard additions. Three-tier confidence model (0.75 / 0.90 / 0.97). Zero-tolerance auto-block for 10 high-risk secret types. SARIF 2.1.0 output. Runs fully locally — no external service required.</td>
|
|
1357
|
+
<td>Security / DevSecOps teams</td>
|
|
1358
|
+
</tr>
|
|
1359
|
+
<tr>
|
|
1360
|
+
<td><code>spanforge.sdk.audit</code></td>
|
|
1361
|
+
<td><code>SFAuditClient</code> — <code>append(record, schema_key)</code> with HMAC-SHA256 chaining, <code>query()</code> SQLite index with full-text and date-range filters, <code>verify_chain()</code> tamper detection, <code>get_trust_scorecard()</code> T.R.U.S.T. dimensions (hallucination · PII hygiene · secrets hygiene · gate pass-rate · compliance posture), <code>generate_article30_record()</code> GDPR Article 30 RoPA, <code>export()</code> JSONL/CSV/compressed, <code>sign()</code>, <code>get_status()</code>. BYOS routing via <code>SPANFORGE_AUDIT_BYOS_PROVIDER</code> (S3 / Azure / GCS / R2). Strict-schema mode, configurable retention years, optional SQLite persistence. 123 tests, 85 % coverage, mypy strict clean.</td>
|
|
1362
|
+
<td>Compliance / security / audit teams</td>
|
|
1363
|
+
</tr>
|
|
1364
|
+
<tr>
|
|
1365
|
+
<td><code>spanforge.sdk.observe</code></td>
|
|
1366
|
+
<td><code>SFObserveClient</code> — <code>emit_span(name, attributes)</code> builds OTel-compliant spans with W3C traceparent / baggage injection and OTel GenAI semantic attributes; <code>export_spans(spans, receiver_config=...)</code> routes to <code>local</code> / <code>otlp</code> / <code>datadog</code> / <code>grafana</code> / <code>splunk</code> / <code>elastic</code>; <code>add_annotation(event_type, payload)</code> / <code>get_annotations(event_type, from_dt, to_dt)</code> annotation store; <code>get_status()</code>, <code>healthy</code>, <code>last_export_at</code> health probes. Sampling via <code>SPANFORGE_OBSERVE_SAMPLER</code> (<code>always_on</code> / <code>always_off</code> / <code>parent_based</code> / <code>trace_id_ratio</code>). 139 tests, 97% coverage, mypy strict + bandit clean. <em>(Phase 6, v2.0.5+)</em></td>
|
|
1367
|
+
<td>Platform / MLOps / observability teams</td>
|
|
1368
|
+
</tr>
|
|
1369
|
+
<tr>
|
|
1370
|
+
<td><code>spanforge.sdk.alert</code></td>
|
|
1371
|
+
<td><code>SFAlertClient</code> — <code>publish(topic, payload, *, severity, project_id) → PublishResult</code> routes to all configured sinks with deduplication, rate-limiting, alert grouping, and maintenance-window suppression; <code>acknowledge(alert_id)</code> cancels CRITICAL escalation; <code>register_topic()</code> custom topic registry; <code>set_maintenance_window()</code> / <code>remove_maintenance_windows()</code>; <code>get_alert_history()</code> with filtering; <code>get_status()</code> / <code>healthy</code> health probes. Built-in sinks: <code>WebhookAlerter</code> (HMAC), <code>OpsGenieAlerter</code>, <code>VictorOpsAlerter</code>, <code>IncidentIOAlerter</code>, <code>SMSAlerter</code> (Twilio), <code>TeamsAdaptiveCardAlerter</code>. Auto-discovery from <code>SPANFORGE_ALERT_*</code> env vars. Per-sink circuit breakers. 95 tests, mypy strict + bandit clean. <em>(Phase 7, v2.0.6+)</em></td>
|
|
1372
|
+
<td>Platform / SRE / on-call teams</td>
|
|
1373
|
+
</tr>
|
|
1374
|
+
<tr>
|
|
1375
|
+
<td><code>spanforge.sdk.gate</code></td>
|
|
1376
|
+
<td><code>SFGateClient</code> — <code>evaluate(gate_id, payload) → GateEvaluationResult</code>, <code>evaluate_prri(prri_score) → PRRIResult</code>, <code>run_pipeline(gate_config_path) → GateRunResult</code>, <code>get_artifact(gate_id)</code>, <code>list_artifacts()</code>, <code>purge_artifacts(older_than_days)</code>, <code>get_status() → GateStatusInfo</code>, <code>configure(config)</code>. Six built-in gate executors: <code>schema_validation</code>, <code>dependency_security</code>, <code>secrets_scan</code>, <code>performance_regression</code>, <code>halluccheck_prri</code>, <code>halluccheck_trust</code>. PRRI three-tier verdict (<code>GREEN</code>/<code>AMBER</code>/<code>RED</code>), <code>GateArtifact</code> store with configurable retention, composite trust gate (HRI rate + PII window + secrets window), five exception types. 174 tests, mypy strict + bandit clean. <em>(Phase 8, v2.0.7+)</em></td>
|
|
1377
|
+
<td>DevOps / CI / platform teams</td>
|
|
1378
|
+
</tr>
|
|
1379
|
+
<tr>
|
|
1380
|
+
<td><code>spanforge.sdk.config</code></td>
|
|
1381
|
+
<td><code>load_config_file(path?)</code> — auto-discovers <code>.halluccheck.toml</code> or falls back to env-var defaults. <code>validate_config(block)</code> / <code>validate_config_strict(block)</code> schema validation. <code>SFConfigBlock</code>, <code>SFServiceToggles</code>, <code>SFLocalFallbackConfig</code>, <code>SFPIIConfig</code>, <code>SFSecretsConfig</code> typed dataclasses. Env-var overrides: <code>SPANFORGE_ENDPOINT</code>, <code>SPANFORGE_API_KEY</code>, <code>SPANFORGE_PROJECT_ID</code>, <code>SPANFORGE_PII_THRESHOLD</code>, <code>SPANFORGE_SECRETS_AUTO_BLOCK</code>, <code>SPANFORGE_LOCAL_TOKEN</code>, <code>SPANFORGE_FALLBACK_TIMEOUT_MS</code>. <em>(Phase 9, v2.0.8+)</em></td>
|
|
1382
|
+
<td>All teams / platform engineers</td>
|
|
1383
|
+
</tr>
|
|
1384
|
+
<tr>
|
|
1385
|
+
<td><code>spanforge.sdk.registry</code></td>
|
|
1386
|
+
<td><code>ServiceRegistry.get_instance()</code> — thread-safe singleton holding all 11 service clients. <code>run_startup_check()</code> pings all enabled services (status: up / degraded / down). <code>status_response()</code> returns per-service <code>{status, latency_ms, last_checked_at}</code>. <code>start_background_checker()</code> launches a daemon thread re-checking every 60 s. <code>ServiceHealth</code>, <code>ServiceStatus</code> typed enums. <em>(Phase 9, v2.0.8+)</em></td>
|
|
1387
|
+
<td>Platform / SRE teams</td>
|
|
1388
|
+
</tr>
|
|
1389
|
+
<tr>
|
|
1390
|
+
<td><code>spanforge.sdk.fallback</code></td>
|
|
1391
|
+
<td>8 local-mode fallback implementations: <code>pii_fallback()</code> (regex scan), <code>secrets_fallback()</code> (regex scan), <code>audit_fallback()</code> (HMAC-chained JSONL), <code>observe_fallback()</code> (OTLP JSON to stdout), <code>alert_fallback()</code> (log to stderr), <code>identity_fallback()</code> (trust local token), <code>gate_fallback()</code> (local gate engine), <code>cec_fallback()</code> (local JSONL). All emit WARNING when active. <em>(Phase 9, v2.0.8+)</em></td>
|
|
1392
|
+
<td>All teams (automatic)</td>
|
|
1393
|
+
</tr>
|
|
1394
|
+
<tr>
|
|
1395
|
+
<td><code>spanforge.sdk.trust</code></td>
|
|
1396
|
+
<td><code>SFTrustClient</code> — <code>get_scorecard(project_id, *, from_dt, to_dt, weights) → TrustScorecardResponse</code> aggregates five T.R.U.S.T. dimensions (Transparency · Reliability · UserTrust · Security · Traceability) with configurable weights. <code>get_badge(project_id) → TrustBadgeResult</code> generates an SVG badge with colour-band (green ≥ 80, amber ≥ 60, red < 60). <code>get_history(project_id, *, buckets) → list[TrustHistoryEntry]</code> returns time-series snapshots. <code>get_status()</code> health probe. Reads from sf-audit trust records. 28 tests, mypy strict + bandit clean. <em>(Phase 10, v2.0.9+)</em></td>
|
|
1397
|
+
<td>Compliance / platform / ML teams</td>
|
|
1398
|
+
</tr>
|
|
1399
|
+
<tr>
|
|
1400
|
+
<td><code>spanforge.sdk.pipelines</code></td>
|
|
1401
|
+
<td>5 HallucCheck ↔ SpanForge pipeline integrations: <code>score_pipeline(text)</code> (PII → secrets → observe → audit), <code>bias_pipeline(report)</code> (PII → audit → alert → anonymise), <code>monitor_pipeline(event)</code> (observe → alert → OTel export), <code>risk_pipeline(prri_score)</code> (PRRI → alert → gate → CEC), <code>benchmark_pipeline(results)</code> (audit → alert → anonymise). Each returns <code>PipelineResult</code> with audit trail. <em>(Phase 10, v2.0.9+)</em></td>
|
|
1402
|
+
<td>ML / eval / platform teams</td>
|
|
1403
|
+
</tr>
|
|
1404
|
+
<td><code>SFCECClient</code> — <code>build_bundle(project_id, date_range, frameworks)</code> assembles a signed ZIP with <code>manifest.json</code>, <code>clause_map.json</code>, <code>chain_proof.json</code>, <code>attestation.json</code>, <code>rfc3161_timestamp.tsr</code>, and 6 NDJSON evidence directories. HMAC-SHA256 manifest signing, BYOS detection. <code>verify_bundle(zip_path)</code> re-verifies HMAC + chain + timestamp. <code>generate_dpa(project_id, controller_details, processor_details)</code> produces a GDPR Article 28 Data Processing Agreement. <code>get_status()</code> returns bundle count, BYOS provider, and last bundle timestamp. Supports all 5 frameworks: <code>eu_ai_act</code>, <code>iso_42001</code>, <code>nist_ai_rmf</code>, <code>iso27001</code>, <code>soc2</code>. 148 tests, 87% coverage, mypy strict + bandit clean. <em>(Phase 5, v2.0.4+)</em></td>
|
|
1405
|
+
<td>Compliance / legal / audit teams</td>
|
|
1406
|
+
</tr>
|
|
1407
|
+
<tr>
|
|
1408
|
+
<td><code>spanforge.sdk</code></td>
|
|
1409
|
+
<td>Pre-built <code>sf_identity</code>, <code>sf_pii</code>, <code>sf_secrets</code>, <code>sf_audit</code>, <code>sf_cec</code>, <code>sf_observe</code>, <code>sf_alert</code>, <code>sf_gate</code>, <code>sf_trust</code>, <code>sf_enterprise</code>, <code>sf_security</code>, <code>sf_rag</code>, and <code>sf_feedback</code> singletons loaded from env vars on first import. <code>SFClientConfig</code>, <code>SecretStr</code>, full exception hierarchy (<code>SFAuthError</code>, <code>SFBruteForceLockedError</code>, <code>SFPIINotRedactedError</code>, <code>SFPIIBlockedError</code>, <code>SFPIIDPDPConsentMissingError</code>, <code>SFSecretsBlockedError</code>, <code>SFAuditSchemaError</code>, <code>SFAuditAppendError</code>, <code>SFAuditQueryError</code>, <code>SFCECError</code>, <code>SFCECBuildError</code>, <code>SFCECVerifyError</code>, <code>SFCECExportError</code>, <code>SFObserveError</code>, <code>SFObserveExportError</code>, <code>SFObserveEmitError</code>, <code>SFObserveAnnotationError</code>, <code>SFAlertError</code>, <code>SFAlertPublishError</code>, <code>SFAlertRateLimitedError</code>, <code>SFAlertQueueFullError</code>, <code>SFGateError</code>, <code>SFGateEvaluationError</code>, <code>SFGatePipelineError</code>, <code>SFGateTrustFailedError</code>, <code>SFGateSchemaError</code>, <code>SFConfigError</code>, <code>SFConfigValidationError</code>, <code>SFStartupError</code>, <code>SFServiceUnavailableError</code>, <code>SFTrustComputeError</code>, <code>SFPipelineError</code>, <code>SFEnterpriseError</code>, <code>SFIsolationError</code>, <code>SFDataResidencyError</code>, <code>SFEncryptionError</code>, <code>SFFIPSError</code>, <code>SFAirGapError</code>, <code>SFSecurityScanError</code>, <code>SFSecretsInLogsError</code>, …), and all value-object types exported from the top-level package. <code>load_config_file()</code>, <code>validate_config()</code>, <code>validate_config_strict()</code>, <code>ServiceRegistry</code>, and 8 fallback functions re-exported for convenience.</td>
|
|
1410
|
+
<td>All teams</td>
|
|
1411
|
+
</tr>
|
|
1412
|
+
</tbody>
|
|
1413
|
+
</table>
|
|
1414
|
+
|
|
1415
|
+
---
|
|
1416
|
+
|
|
1417
|
+
## Quality
|
|
1418
|
+
|
|
1419
|
+
- **5 863 tests** passing (14 skipped) — unit, integration, property-based (Hypothesis), performance benchmarks
|
|
1420
|
+
- **≥ 91% line and branch coverage** — 90% minimum enforced in CI
|
|
1421
|
+
- **Zero required dependencies** — entire core runs on Python stdlib
|
|
1422
|
+
- **Typed** — full `py.typed` marker; mypy + pyright clean
|
|
1423
|
+
- **Frozen v2 trace schema** — `llm.trace.*` payload fields never break between minor releases
|
|
1424
|
+
- **Async-safe** — `contextvars`-based context propagation across asyncio, threads, and executors
|
|
1425
|
+
|
|
1426
|
+
---
|
|
1427
|
+
|
|
1428
|
+
## Development
|
|
1429
|
+
|
|
1430
|
+
```bash
|
|
1431
|
+
git clone https://github.com/veerarag1973/spanforge.git
|
|
1432
|
+
cd spanforge
|
|
1433
|
+
python -m venv .venv && .venv\Scripts\activate
|
|
1434
|
+
pip install -e ".[dev]"
|
|
1435
|
+
pytest # 5 351 tests
|
|
1436
|
+
```
|
|
1437
|
+
|
|
1438
|
+
<details>
|
|
1439
|
+
<summary><strong>Code quality</strong></summary>
|
|
1440
|
+
|
|
1441
|
+
```bash
|
|
1442
|
+
ruff check . && ruff format .
|
|
1443
|
+
mypy spanforge
|
|
1444
|
+
pytest --cov # >=90% required
|
|
1445
|
+
```
|
|
1446
|
+
|
|
1447
|
+
</details>
|
|
1448
|
+
|
|
1449
|
+
<details>
|
|
1450
|
+
<summary><strong>Build docs</strong></summary>
|
|
1451
|
+
|
|
1452
|
+
```bash
|
|
1453
|
+
pip install -e ".[docs]"
|
|
1454
|
+
cd docs && sphinx-build -b html . _build/html
|
|
1455
|
+
```
|
|
1456
|
+
|
|
1457
|
+
</details>
|
|
1458
|
+
|
|
1459
|
+
---
|
|
1460
|
+
|
|
1461
|
+
## Versioning
|
|
1462
|
+
|
|
1463
|
+
spanforge implements **RFC-0001** (AI Compliance Standard for Agentic AI Systems). Current schema version: **2.0**.
|
|
1464
|
+
|
|
1465
|
+
This project follows [Semantic Versioning](https://semver.org/). The `llm.trace.*` namespace is additionally **frozen at v2** — even major releases won't remove fields from `SpanPayload`, `AgentRunPayload`, or `AgentStepPayload`.
|
|
1466
|
+
|
|
1467
|
+
See [docs/changelog.md](docs/changelog.md) for the full version history.
|
|
1468
|
+
|
|
1469
|
+
---
|
|
1470
|
+
|
|
1471
|
+
## Contributing
|
|
1472
|
+
|
|
1473
|
+
Contributions welcome — see the [Contributing Guide](docs/contributing.md). All new code must maintain ≥ 90% coverage. Run `ruff` and `mypy` before submitting.
|
|
1474
|
+
|
|
1475
|
+
---
|
|
1476
|
+
|
|
1477
|
+
## Community
|
|
1478
|
+
|
|
1479
|
+
- **[Discussions](https://github.com/veerarag1973/spanforge/discussions)** — questions, ideas, show-and-tell
|
|
1480
|
+
- **[Issues](https://github.com/veerarag1973/spanforge/issues)** — bug reports and feature requests
|
|
1481
|
+
- **[SECURITY.md](SECURITY.md)** — responsible disclosure process
|
|
1482
|
+
- **[Code of Conduct](CODE_OF_CONDUCT.md)** — Contributor Covenant v2.1
|
|
1483
|
+
|
|
1484
|
+
> Topics: `ai-compliance` `ai-governance` `eu-ai-act` `gdpr` `soc2` `audit-trail` `pii-redaction` `hmac-signing` `llm-governance` `python`
|
|
1485
|
+
|
|
1486
|
+
---
|
|
1487
|
+
|
|
1488
|
+
## License
|
|
1489
|
+
|
|
1490
|
+
**[PolyForm Noncommercial License 1.0.0](LICENSE)**
|
|
1491
|
+
|
|
1492
|
+
- ✅ Free for personal use, research, education, open-source projects, and non-profit organisations.
|
|
1493
|
+
- ❌ Commercial use (running as a paid service, internal business use, SaaS integration) requires a commercial license.
|
|
1494
|
+
|
|
1495
|
+
To obtain a commercial license: **sriram@getspanforge.com** | [getspanforge.com/pricing](https://getspanforge.com/pricing)
|
|
1496
|
+
|
|
1497
|
+
> Enterprise features (SSO, air-gapped deployment, dedicated support, SLAs) are available in **SpanForge Enterprise** — a separate commercial product.
|
|
1498
|
+
|
|
1499
|
+
---
|
|
1500
|
+
|
|
1501
|
+
<p align="center">
|
|
1502
|
+
Built for teams that take AI governance seriously.<br/>
|
|
1503
|
+
<a href="docs/index.md">Docs</a> —
|
|
1504
|
+
<a href="docs/runtime-governance.md">Runtime Governance</a> —
|
|
1505
|
+
<a href="docs/quickstart.md">Quickstart</a> —
|
|
1506
|
+
<a href="docs/api/index.md">API Reference</a> —
|
|
1507
|
+
<a href="https://github.com/veerarag1973/spanforge/discussions">Discussions</a> —
|
|
1508
|
+
<a href="https://github.com/veerarag1973/spanforge/issues">Report a bug</a>
|
|
1509
|
+
</p>
|