cleanlib-sdk 0.4.2__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cleanlib_sdk-0.4.4/CHANGELOG.md +41 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/PKG-INFO +12 -17
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/README.md +7 -12
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/__init__.py +1 -1
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/pyproject.toml +20 -5
- cleanlib_sdk-0.4.2/bitbucket-pipelines.yml +0 -55
- cleanlib_sdk-0.4.2/tests/__init__.py +0 -0
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/CORPUS-README.md +0 -96
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/EXPECTED.json +0 -50
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-allow-clean.json +0 -7
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-allow-recommended.json +0 -17
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-degraded-stale.json +0 -18
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-deny-exploitation-critical.json +0 -21
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-deny-kev.json +0 -21
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-unreachable.json +0 -16
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-warn-abandoned.json +0 -14
- cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-warn-has-remediation.json +0 -17
- cleanlib_sdk-0.4.2/tests/test_attestation.py +0 -117
- cleanlib_sdk-0.4.2/tests/test_client_construct.py +0 -46
- cleanlib_sdk-0.4.2/tests/test_error_mapping.py +0 -90
- cleanlib_sdk-0.4.2/tests/test_v041_contract_and_clients.py +0 -221
- cleanlib_sdk-0.4.2/tests/test_v042_enrich_cascade.py +0 -603
- cleanlib_sdk-0.4.2/tests/test_v04_rich_data_and_verbs.py +0 -205
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/.gitignore +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/client.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/derive_status.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/errors.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/__init__.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/enrich_client.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/enrich_types.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/remediation_client.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/types.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/verdict_client.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/reason_codes.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/schema/__init__.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/schema/verdict_envelope_v1.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/transport.py +0 -0
- {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/types.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# cleanlib-sdk changelog
|
|
2
|
+
|
|
3
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
4
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
|
+
|
|
6
|
+
## [0.4.4] — 2026-06-04
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- `cleanlib_sdk.__version__` synchronized with the package manifest version.
|
|
11
|
+
Previously the in-code `__version__` reported `0.4.2` while the published
|
|
12
|
+
artifact was `0.4.3` — telemetry that relied on `__version__` for User-Agent
|
|
13
|
+
composition was under-reporting deployment penetration.
|
|
14
|
+
- Wheel + sdist now include `CHANGELOG.md`. Customers running `pip download`
|
|
15
|
+
+ tar inspection (or browsing the PyPI release files page) see the version
|
|
16
|
+
history alongside the package code.
|
|
17
|
+
|
|
18
|
+
## [0.4.3] — 2026-06-03
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- `pyproject.toml` `[project.urls]` table sanitized: `Homepage`,
|
|
23
|
+
`Documentation`, and `Bug Tracker` now point at `cleanlibrary.clnstrt.dev`
|
|
24
|
+
rather than the internal source-of-truth URLs that previously rendered on
|
|
25
|
+
the PyPI listing page.
|
|
26
|
+
- `README.md` cross-references brand-clean: repo-internal links replaced with
|
|
27
|
+
the customer-facing `cleanlibrary.clnstrt.dev` documentation site and
|
|
28
|
+
cross-language SDK registry pages (crates.io, pkg.clnstrt.dev, npmjs.com).
|
|
29
|
+
|
|
30
|
+
### Notes
|
|
31
|
+
|
|
32
|
+
- No runtime API or wire-protocol changes; this is a metadata + docs ship.
|
|
33
|
+
- Verified via `python -m build` against the resulting `cleanlib_sdk-0.4.3-py3-none-any.whl`
|
|
34
|
+
`METADATA` + `cleanlib_sdk-0.4.3.tar.gz` `PKG-INFO`: zero
|
|
35
|
+
internal-source URL references.
|
|
36
|
+
|
|
37
|
+
## 0.4.2 — enrich verb cascade + F4 default-flip to cleanlib-enrich
|
|
38
|
+
|
|
39
|
+
## 0.4.1 — per-domain HTTP client split (HttpRemediationClient) + schema/reason-codes mirror + DeriveStatus + Client @deprecated
|
|
40
|
+
|
|
41
|
+
## 0.4.0 — verb cascade + rich-data
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cleanlib-sdk
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary: CleanLibrary Python SDK — HttpVerdictClient + HttpRemediationClient + HttpEnrichClient triad (sister-shape with @cleanstart/cleanlib-sdk v0.4.
|
|
5
|
-
Project-URL: Homepage, https://
|
|
6
|
-
Project-URL:
|
|
7
|
-
Project-URL:
|
|
3
|
+
Version: 0.4.4
|
|
4
|
+
Summary: CleanLibrary Python SDK — HttpVerdictClient + HttpRemediationClient + HttpEnrichClient triad (sister-shape with @cleanstart/cleanlib-sdk v0.4.4)
|
|
5
|
+
Project-URL: Homepage, https://cleanlibrary.clnstrt.dev
|
|
6
|
+
Project-URL: Documentation, https://cleanlibrary.clnstrt.dev/docs/sdk-python
|
|
7
|
+
Project-URL: Bug Tracker, https://cleanlibrary.clnstrt.dev/support
|
|
8
8
|
Author: CleanStart
|
|
9
9
|
License: Proprietary
|
|
10
10
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
@@ -23,24 +23,18 @@ Requires-Dist: pytest>=8; extra == 'dev'
|
|
|
23
23
|
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
25
|
|
|
26
|
-
# cleanlib-sdk
|
|
26
|
+
# cleanlib-sdk
|
|
27
27
|
|
|
28
28
|
CleanLibrary Python SDK — `asyncio` + `httpx`; mirrors the Rust `cleanlib-client` HTTP surface.
|
|
29
29
|
|
|
30
|
-
**Status**: `v0.
|
|
30
|
+
**Status**: `v0.4.3` — production-ready.
|
|
31
31
|
|
|
32
|
-
## Install
|
|
32
|
+
## Install
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
pip install cleanlib-sdk
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
For cycle-4 substrate, install from this repo:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
pip install git+https://bitbucket.org/triamsec/cleanlib-sdk-py.git
|
|
42
|
-
```
|
|
43
|
-
|
|
44
38
|
## Usage
|
|
45
39
|
|
|
46
40
|
```python
|
|
@@ -93,9 +87,10 @@ ruff check .
|
|
|
93
87
|
|
|
94
88
|
## Cross-references
|
|
95
89
|
|
|
96
|
-
- [
|
|
97
|
-
-
|
|
98
|
-
-
|
|
90
|
+
- [CleanLibrary docs](https://cleanlibrary.clnstrt.dev) — customer documentation portal
|
|
91
|
+
- Rust SDK: [`cleanlib-client`](https://crates.io/crates/cleanlib-client) — reference implementation
|
|
92
|
+
- Go SDK: [`cleanlib-sdk-go`](https://pkg.clnstrt.dev/cleanlib-sdk-go)
|
|
93
|
+
- JavaScript SDK: [`@cleanstart/cleanlib-sdk`](https://www.npmjs.com/package/@cleanstart/cleanlib-sdk)
|
|
99
94
|
|
|
100
95
|
## License
|
|
101
96
|
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
# cleanlib-sdk
|
|
1
|
+
# cleanlib-sdk
|
|
2
2
|
|
|
3
3
|
CleanLibrary Python SDK — `asyncio` + `httpx`; mirrors the Rust `cleanlib-client` HTTP surface.
|
|
4
4
|
|
|
5
|
-
**Status**: `v0.
|
|
5
|
+
**Status**: `v0.4.3` — production-ready.
|
|
6
6
|
|
|
7
|
-
## Install
|
|
7
|
+
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
pip install cleanlib-sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
For cycle-4 substrate, install from this repo:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
pip install git+https://bitbucket.org/triamsec/cleanlib-sdk-py.git
|
|
17
|
-
```
|
|
18
|
-
|
|
19
13
|
## Usage
|
|
20
14
|
|
|
21
15
|
```python
|
|
@@ -68,9 +62,10 @@ ruff check .
|
|
|
68
62
|
|
|
69
63
|
## Cross-references
|
|
70
64
|
|
|
71
|
-
- [
|
|
72
|
-
-
|
|
73
|
-
-
|
|
65
|
+
- [CleanLibrary docs](https://cleanlibrary.clnstrt.dev) — customer documentation portal
|
|
66
|
+
- Rust SDK: [`cleanlib-client`](https://crates.io/crates/cleanlib-client) — reference implementation
|
|
67
|
+
- Go SDK: [`cleanlib-sdk-go`](https://pkg.clnstrt.dev/cleanlib-sdk-go)
|
|
68
|
+
- JavaScript SDK: [`@cleanstart/cleanlib-sdk`](https://www.npmjs.com/package/@cleanstart/cleanlib-sdk)
|
|
74
69
|
|
|
75
70
|
## License
|
|
76
71
|
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cleanlib-sdk"
|
|
7
|
-
version = "0.4.
|
|
8
|
-
description = "CleanLibrary Python SDK — HttpVerdictClient + HttpRemediationClient + HttpEnrichClient triad (sister-shape with @cleanstart/cleanlib-sdk v0.4.
|
|
7
|
+
version = "0.4.4"
|
|
8
|
+
description = "CleanLibrary Python SDK — HttpVerdictClient + HttpRemediationClient + HttpEnrichClient triad (sister-shape with @cleanstart/cleanlib-sdk v0.4.4)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { text = "Proprietary" }
|
|
@@ -32,13 +32,28 @@ dev = [
|
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
[project.urls]
|
|
35
|
-
Homepage = "https://
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
Homepage = "https://cleanlibrary.clnstrt.dev"
|
|
36
|
+
Documentation = "https://cleanlibrary.clnstrt.dev/docs/sdk-python"
|
|
37
|
+
"Bug Tracker" = "https://cleanlibrary.clnstrt.dev/support"
|
|
38
38
|
|
|
39
39
|
[tool.hatch.build.targets.wheel]
|
|
40
40
|
packages = ["cleanlib_sdk"]
|
|
41
41
|
|
|
42
|
+
# v0.4.4 CLEANLIB-49: ship CHANGELOG.md inside the package so customers
|
|
43
|
+
# reading the PyPI listing (or running pip download + tar inspection) see
|
|
44
|
+
# the version history.
|
|
45
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
46
|
+
"CHANGELOG.md" = "cleanlib_sdk/CHANGELOG.md"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.sdist]
|
|
49
|
+
include = [
|
|
50
|
+
"cleanlib_sdk/**",
|
|
51
|
+
"README.md",
|
|
52
|
+
"CHANGELOG.md",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
"pyproject.toml",
|
|
55
|
+
]
|
|
56
|
+
|
|
42
57
|
[tool.pytest.ini_options]
|
|
43
58
|
asyncio_mode = "auto"
|
|
44
59
|
testpaths = ["tests"]
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# CleanLibrary Python SDK CI — per workspace §C.5 + §C.6 + pen #16 forward fix.
|
|
2
|
-
#
|
|
3
|
-
# Mirrors the cleanlib repo's commit-prefix discipline + rebase-required
|
|
4
|
-
# detector. Uses a separate CLEANLIB-N counter per sdk-substrate-rev1.md §8.
|
|
5
|
-
|
|
6
|
-
image: python:3.12-slim
|
|
7
|
-
|
|
8
|
-
pipelines:
|
|
9
|
-
default:
|
|
10
|
-
- step:
|
|
11
|
-
name: Validate commit message prefix
|
|
12
|
-
script:
|
|
13
|
-
# Each commit on the PR branch (since divergence from main) must start with
|
|
14
|
-
# a CLEANLIB-N prefix per workspace §6.9 discipline. --no-merges per pen #16
|
|
15
|
-
# avoids false-positives on BB-synthesized merge commits.
|
|
16
|
-
- |
|
|
17
|
-
apt-get update -qq && apt-get install -y -qq git >/dev/null
|
|
18
|
-
BASE_REF=${BITBUCKET_PR_DESTINATION_BRANCH:-main}
|
|
19
|
-
git fetch origin "$BASE_REF" || true
|
|
20
|
-
git log --no-merges "origin/$BASE_REF..HEAD" --pretty=format:"%H %s" | while read -r line; do
|
|
21
|
-
MSG=${line#* }
|
|
22
|
-
case "$MSG" in
|
|
23
|
-
CLEANLIB-*) ;;
|
|
24
|
-
*) echo "❌ commit missing CLEANLIB-N prefix: $line"; exit 1;;
|
|
25
|
-
esac
|
|
26
|
-
done
|
|
27
|
-
echo "✅ commit prefixes OK"
|
|
28
|
-
|
|
29
|
-
- step:
|
|
30
|
-
name: Rebase-required detector
|
|
31
|
-
script:
|
|
32
|
-
# Mirrors cleanlib repo §C.6: if merge-base is not on main's HEAD, ask for rebase.
|
|
33
|
-
- |
|
|
34
|
-
apt-get update -qq && apt-get install -y -qq git >/dev/null
|
|
35
|
-
BASE_REF=${BITBUCKET_PR_DESTINATION_BRANCH:-main}
|
|
36
|
-
git fetch origin "$BASE_REF"
|
|
37
|
-
MB=$(git merge-base "origin/$BASE_REF" HEAD)
|
|
38
|
-
HEAD_REMOTE=$(git rev-parse "origin/$BASE_REF")
|
|
39
|
-
if [ "$MB" != "$HEAD_REMOTE" ]; then
|
|
40
|
-
echo "❌ Branch is behind origin/$BASE_REF; rebase before merging."
|
|
41
|
-
echo " merge-base: $MB"
|
|
42
|
-
echo " origin/$BASE_REF: $HEAD_REMOTE"
|
|
43
|
-
exit 1
|
|
44
|
-
fi
|
|
45
|
-
echo "✅ branch current with origin/$BASE_REF"
|
|
46
|
-
|
|
47
|
-
- step:
|
|
48
|
-
name: Lint + test
|
|
49
|
-
caches:
|
|
50
|
-
- pip
|
|
51
|
-
script:
|
|
52
|
-
- pip install --quiet --upgrade pip
|
|
53
|
-
- pip install --quiet -e ".[dev]"
|
|
54
|
-
- ruff check .
|
|
55
|
-
- pytest -q
|
|
File without changes
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# cleanlib-contract-fixtures
|
|
2
|
-
|
|
3
|
-
**Cross-SDK contract fixture corpus.** Source-of-truth fixtures that every CleanLibrary SDK consumer asserts identical `DeriveStatus` results against. The corpus locks against the **`VerdictEnvelopeV1`** schema published in `@cleanstart/cleanlib-sdk@0.4.1`.
|
|
4
|
-
|
|
5
|
-
## Consumers (4)
|
|
6
|
-
|
|
7
|
-
| SDK | Repo | Test harness | Schema validator |
|
|
8
|
-
|---|---|---|---|
|
|
9
|
-
| sdk-js | `triamsec/cleanlib-sdk-js` (npm `@cleanstart/cleanlib-sdk`) | vitest | ajv |
|
|
10
|
-
| sdk-py | `triamsec/cleanlib-sdk-py` (PyPI `cleanlib-sdk`) | pytest | `jsonschema` |
|
|
11
|
-
| sdk-go | `triamsec/cleanlib-sdk-go` (Go modules; same path) | `go test` | `github.com/xeipuuv/gojsonschema` |
|
|
12
|
-
| cleanlib-client (Rust) | `triamsec/cleanlib` workspace member | `cargo test` | `jsonschema` crate |
|
|
13
|
-
|
|
14
|
-
Each consumer pulls this corpus as a git submodule (or vendors under `test/fixtures/`); CI fails on `DeriveStatus(fixture) != expected_per_EXPECTED.json` for any fixture.
|
|
15
|
-
|
|
16
|
-
## Schema lock
|
|
17
|
-
|
|
18
|
-
v1.0.0 of this corpus locks against:
|
|
19
|
-
- Tarball: `@cleanstart/cleanlib-sdk@0.4.1` (sha-1 `b5f00c160907a6ea1f490f14a9bda6f6de34b8b6`)
|
|
20
|
-
- Schema: `https://cleanstart.com/schemas/verdict-envelope.v1.json` (`VerdictEnvelopeV1Schema` exported from `dist/schema/verdict-envelope.v1.js`)
|
|
21
|
-
- ReasonCode registry: `dist/reason-codes.js` (15 codes)
|
|
22
|
-
- Freshness-precedence rule: ratified 2026-05-28; documented in schema `reason_code.description` + `reason-codes.js` comment
|
|
23
|
-
|
|
24
|
-
## VerdictEnvelopeV1 — top-level shape
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
required: [status, reason_code, human_message, as_of]
|
|
28
|
-
optional: rich_data, remediation, exploitability, availability{kev,epss,exploitation_fusion}
|
|
29
|
-
status enum: [ALLOW, WARN, DENY] ← server-side tri-state only
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**`UNREACHABLE` and `LIVE_DEGRADED` are NOT envelope status values.** They are client-tier states:
|
|
33
|
-
- `UNREACHABLE` — CLI exit-code 3 on SDK transport-error; no envelope
|
|
34
|
-
- `LIVE_DEGRADED` — VS Code extension status-bar state on cache-fallback; surfaces as `reason_code=VERDICT_DEGRADED_STALE` when an envelope IS assembled from a stale cache hit, else as an out-of-band transport state
|
|
35
|
-
|
|
36
|
-
The corpus's `verdict-unreachable.json` documents the transport-error shape (NOT a VerdictEnvelopeV1) for SDK transport-tier contract tests.
|
|
37
|
-
|
|
38
|
-
## Fixture → (status, reason_code) contract
|
|
39
|
-
|
|
40
|
-
Per the freshness-precedence rule (App dispatch §4 + Client dispatch §2.3 binding contract):
|
|
41
|
-
- **Substance precedence** — signals top-to-bottom (exploitation_critical > kev > obfuscation > has_remediation > abandonment > clean); `unavailable` substrate falls through to the next rule
|
|
42
|
-
- **Freshness override** — `degraded_stale` substrate KEEPS the substance-derived status tier but rewrites `reason_code` → `VERDICT_DEGRADED_STALE`
|
|
43
|
-
- **Block tie-break in remediation** — `fix > recommended_version > other blocks`
|
|
44
|
-
- **Server-side `VERDICT_DEGRADED_STALE` ≠ client-side `LIVE_DEGRADED`** — distinct concepts; never conflated
|
|
45
|
-
|
|
46
|
-
| Fixture | Status | Reason code | Driving fields |
|
|
47
|
-
|---|---|---|---|
|
|
48
|
-
| `verdict-allow-clean.json` | ALLOW | VERDICT_CLEAN | (no sub-objects) |
|
|
49
|
-
| `verdict-allow-recommended.json` | ALLOW | VERDICT_RECOMMENDED_VERSION_NEWER | `rich_data.recommended_version` (benign upgrade hint, no remediation block) |
|
|
50
|
-
| `verdict-warn-abandoned.json` | WARN | VERDICT_ABANDONED | `rich_data.abandonment_score >= 0.7` |
|
|
51
|
-
| `verdict-warn-has-remediation.json` | WARN | VERDICT_HAS_REMEDIATION | `remediation.fix` or `remediation.recommended_version` (under `remediation`, NOT `rich_data`) |
|
|
52
|
-
| `verdict-deny-kev.json` | DENY | VERDICT_KEV_LISTED | `exploitability.in_kev=true` + `availability.kev='available'` + `exploitability.exploit_risk_score >= 70` |
|
|
53
|
-
| `verdict-deny-exploitation-critical.json` | DENY | VERDICT_EXPLOITATION_CRITICAL | `exploitability.exploitation_likelihood='CRITICAL'` |
|
|
54
|
-
| `verdict-degraded-stale.json` | WARN | VERDICT_DEGRADED_STALE | substance: HAS_REMEDIATION; freshness override applies (`remediation.fix.availability='degraded_stale'`) |
|
|
55
|
-
| `verdict-unreachable.json` | _(out-of-band)_ | _(out-of-band)_ | transport-error synthetic; not a VerdictEnvelopeV1; CLI exit-3 / extension LIVE_DEGRADED |
|
|
56
|
-
|
|
57
|
-
See `EXPECTED.json` for the machine-readable lookup.
|
|
58
|
-
|
|
59
|
-
## DeriveStatus precedence (canonical spec; SDKs implement independently)
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
if exploitability.exploitation_likelihood == "CRITICAL" → DENY + VERDICT_EXPLOITATION_CRITICAL
|
|
63
|
-
if exploitability.in_kev && availability.kev == "available" && exploit_risk_score >= 70 → DENY + VERDICT_KEV_LISTED
|
|
64
|
-
if rich_data.has_obfuscation → DENY + VERDICT_OBFUSCATED
|
|
65
|
-
if remediation.fix != null || remediation.recommended_version != null → WARN + VERDICT_HAS_REMEDIATION
|
|
66
|
-
if rich_data.abandonment_score >= 0.7 → WARN + VERDICT_ABANDONED
|
|
67
|
-
if rich_data.recommended_version != null → ALLOW + VERDICT_RECOMMENDED_VERSION_NEWER
|
|
68
|
-
default → ALLOW + VERDICT_CLEAN
|
|
69
|
-
|
|
70
|
-
# Then apply the freshness-precedence override:
|
|
71
|
-
if the substance-driving signal's availability == "degraded_stale"
|
|
72
|
-
→ status unchanged; reason_code := VERDICT_DEGRADED_STALE
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
`DeriveStatus` is **not exported from sdk-js** — each SDK implements this algorithm independently against the binding spec. The cross-SDK contract test verifies all 4 implementations agree byte-identically on every fixture's `(status, reason_code)`.
|
|
76
|
-
|
|
77
|
-
## Drift handling
|
|
78
|
-
|
|
79
|
-
Schema changes (new envelope field, renamed key, etc.) MUST land here first; then all 4 SDKs receive a coordinated PR pulling the updated corpus + adjusting derivation cases. Monthly cron CI in each SDK fetches the latest corpus + diffs locally (cycle-8 scope; for cycle-7, manual sync during S1+S2 publish events).
|
|
80
|
-
|
|
81
|
-
## Layout
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
cleanlib-contract-fixtures/
|
|
85
|
-
├── README.md # this file
|
|
86
|
-
├── EXPECTED.json # machine-readable fixture → (status, reason_code) lookup
|
|
87
|
-
└── fixtures/
|
|
88
|
-
├── verdict-allow-clean.json
|
|
89
|
-
├── verdict-allow-recommended.json
|
|
90
|
-
├── verdict-warn-abandoned.json
|
|
91
|
-
├── verdict-warn-has-remediation.json
|
|
92
|
-
├── verdict-deny-kev.json
|
|
93
|
-
├── verdict-deny-exploitation-critical.json
|
|
94
|
-
├── verdict-degraded-stale.json
|
|
95
|
-
└── verdict-unreachable.json # OUT-OF-BAND transport-error; not a VerdictEnvelopeV1
|
|
96
|
-
```
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "Machine-readable fixture → (status, reason_code) lookup, schema-locked against sdk-js v0.4.1 published surface (VerdictEnvelopeV1Schema + ReasonCode registry). Each SDK consumer (sdk-js, sdk-py, sdk-go, cleanlib-client Rust) loads this and asserts DeriveStatus(fixtures[N]) == EXPECTED[N] for every fixture. v1.0.0 of this corpus locks against sdk-js v0.4.1.",
|
|
3
|
-
"_schema_lock": {
|
|
4
|
-
"sdk_js_version": "@cleanstart/cleanlib-sdk@0.4.1",
|
|
5
|
-
"tarball_sha1": "b5f00c160907a6ea1f490f14a9bda6f6de34b8b6",
|
|
6
|
-
"schema_id": "https://cleanstart.com/schemas/verdict-envelope.v1.json",
|
|
7
|
-
"envelope_status_enum": ["ALLOW", "WARN", "DENY"],
|
|
8
|
-
"freshness_precedence_rule_ratified": "2026-05-28"
|
|
9
|
-
},
|
|
10
|
-
"fixtures": {
|
|
11
|
-
"verdict-allow-clean.json": {
|
|
12
|
-
"status": "ALLOW",
|
|
13
|
-
"reason_code": "VERDICT_CLEAN"
|
|
14
|
-
},
|
|
15
|
-
"verdict-allow-recommended.json": {
|
|
16
|
-
"status": "ALLOW",
|
|
17
|
-
"reason_code": "VERDICT_RECOMMENDED_VERSION_NEWER"
|
|
18
|
-
},
|
|
19
|
-
"verdict-warn-abandoned.json": {
|
|
20
|
-
"status": "WARN",
|
|
21
|
-
"reason_code": "VERDICT_ABANDONED"
|
|
22
|
-
},
|
|
23
|
-
"verdict-warn-has-remediation.json": {
|
|
24
|
-
"status": "WARN",
|
|
25
|
-
"reason_code": "VERDICT_HAS_REMEDIATION"
|
|
26
|
-
},
|
|
27
|
-
"verdict-deny-kev.json": {
|
|
28
|
-
"status": "DENY",
|
|
29
|
-
"reason_code": "VERDICT_KEV_LISTED"
|
|
30
|
-
},
|
|
31
|
-
"verdict-deny-exploitation-critical.json": {
|
|
32
|
-
"status": "DENY",
|
|
33
|
-
"reason_code": "VERDICT_EXPLOITATION_CRITICAL"
|
|
34
|
-
},
|
|
35
|
-
"verdict-degraded-stale.json": {
|
|
36
|
-
"status": "WARN",
|
|
37
|
-
"reason_code": "VERDICT_DEGRADED_STALE",
|
|
38
|
-
"_note": "substance:HAS_REMEDIATION + freshness:degraded_stale → status preserved (WARN), reason_code overridden (VERDICT_DEGRADED_STALE) per freshness-precedence rule"
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"_out_of_band": {
|
|
42
|
-
"verdict-unreachable.json": {
|
|
43
|
-
"_kind": "transport_error_synthetic",
|
|
44
|
-
"_note": "NOT a VerdictEnvelopeV1. SDK transport-failure result; CLI maps to UNREACHABLE+exit3; extension maps to LIVE_DEGRADED status-bar (client-tier). No envelope status assigned (schema enum is [ALLOW,WARN,DENY] only).",
|
|
45
|
-
"cli_exit_code": 3,
|
|
46
|
-
"cli_status_label": "UNREACHABLE",
|
|
47
|
-
"extension_status_bar": "LIVE_DEGRADED"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract: no remediation/exploitability/rich-data alerts → status=ALLOW, reason_code=VERDICT_CLEAN. Minimum required envelope shape per VerdictEnvelopeV1Schema. All optional sub-objects omitted.",
|
|
3
|
-
"status": "ALLOW",
|
|
4
|
-
"reason_code": "VERDICT_CLEAN",
|
|
5
|
-
"human_message": "left-pad 1.3.0 — no findings. Allowed.",
|
|
6
|
-
"as_of": "2026-05-28"
|
|
7
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract: benign envelope with recommended_version under rich_data only (NOT under remediation.recommended_version or remediation.fix) → status=ALLOW, reason_code=VERDICT_RECOMMENDED_VERSION_NEWER (specific reason from published ReasonCode registry; F2 ratification supersedes the earlier draft VERDICT_CLEAN mapping). Sister of the cycle-6 cors clean-shape probe.",
|
|
3
|
-
"status": "ALLOW",
|
|
4
|
-
"reason_code": "VERDICT_RECOMMENDED_VERSION_NEWER",
|
|
5
|
-
"human_message": "cors 2.8.4 — clean, but a newer recommended version (2.8.6) is available.",
|
|
6
|
-
"as_of": "2026-05-28",
|
|
7
|
-
"rich_data": {
|
|
8
|
-
"recommended_version": {
|
|
9
|
-
"version": "2.8.6",
|
|
10
|
-
"source": "l1_package_master",
|
|
11
|
-
"detected_at": "",
|
|
12
|
-
"total_versions": 0
|
|
13
|
-
},
|
|
14
|
-
"verdict_source": "llm_anthropic",
|
|
15
|
-
"terminal_state": "completed"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract (freshness-precedence rule ratified 2026-05-28 + binding via App dispatch §4 + Client dispatch §2.3 + verdict-envelope.v1 schema reason_code doc-comment): when underlying substrate availability='degraded_stale' on a block driving a substance-derived reason, the substance-derived tier is PRESERVED and the reason_code OVERRIDES to VERDICT_DEGRADED_STALE. This fixture's substance signal is HAS_REMEDIATION (remediation.fix present); freshness=degraded_stale → status=WARN (preserved) + reason_code=VERDICT_DEGRADED_STALE (overridden). Server-side VERDICT_DEGRADED_STALE is architecturally distinct from client-side LIVE_DEGRADED cache-fallback state.",
|
|
3
|
-
"status": "WARN",
|
|
4
|
-
"reason_code": "VERDICT_DEGRADED_STALE",
|
|
5
|
-
"human_message": "stale-cache-fixture 1.0.0 — remediation data is stale (since 2026-05-21); WARN preserved, reason overridden to freshness.",
|
|
6
|
-
"as_of": "2026-05-28",
|
|
7
|
-
"remediation": {
|
|
8
|
-
"fix": {
|
|
9
|
-
"availability": "degraded_stale",
|
|
10
|
-
"as_of": "2026-05-21"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"availability": {
|
|
14
|
-
"kev": "available",
|
|
15
|
-
"epss": "available",
|
|
16
|
-
"exploitation_fusion": "available"
|
|
17
|
-
}
|
|
18
|
-
}
|
cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-deny-exploitation-critical.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract: exploitability.exploitation_likelihood='CRITICAL' → status=DENY, reason_code=VERDICT_EXPLOITATION_CRITICAL. Highest substance precedence — fires before KEV / obfuscation / remediation / abandonment checks.",
|
|
3
|
-
"status": "DENY",
|
|
4
|
-
"reason_code": "VERDICT_EXPLOITATION_CRITICAL",
|
|
5
|
-
"human_message": "log4j-style-fixture 2.14.0 — CRITICAL active exploitation; immediate action required.",
|
|
6
|
-
"as_of": "2026-05-28",
|
|
7
|
-
"exploitability": {
|
|
8
|
-
"exploitation_likelihood": "CRITICAL",
|
|
9
|
-
"in_kev": true,
|
|
10
|
-
"exploit_risk_score": 99,
|
|
11
|
-
"kev": {
|
|
12
|
-
"cve_id": "CVE-2021-FIXTURE",
|
|
13
|
-
"date_added": "2021-12-15"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"availability": {
|
|
17
|
-
"kev": "available",
|
|
18
|
-
"epss": "available",
|
|
19
|
-
"exploitation_fusion": "available"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract: exploitability.in_kev=true AND exploitability.availability.kev='available' AND exploitability.exploit_risk_score>=70 → status=DENY, reason_code=VERDICT_KEV_LISTED. All three conditions required; ablating any one drops to lower precedence.",
|
|
3
|
-
"status": "DENY",
|
|
4
|
-
"reason_code": "VERDICT_KEV_LISTED",
|
|
5
|
-
"human_message": "kev-listed-fixture 1.0.0 — listed in CISA KEV (CVE-2024-FIXTURE); high exploit-risk.",
|
|
6
|
-
"as_of": "2026-05-28",
|
|
7
|
-
"exploitability": {
|
|
8
|
-
"in_kev": true,
|
|
9
|
-
"exploit_risk_score": 85,
|
|
10
|
-
"exploitation_likelihood": "HIGH",
|
|
11
|
-
"kev": {
|
|
12
|
-
"cve_id": "CVE-2024-FIXTURE",
|
|
13
|
-
"date_added": "2024-08-15"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"availability": {
|
|
17
|
-
"kev": "available",
|
|
18
|
-
"epss": "available",
|
|
19
|
-
"exploitation_fusion": "available"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "OUT-OF-BAND transport-error result — NOT a VerdictEnvelopeV1. This fixture documents the SDK's transport-failure shape (`HttpRemediationClient.getRemediation → {kind:'transient', error}` per sdk-js types/remediation.d.ts). The CLI maps this to UNREACHABLE + exit 3; the VS Code extension maps to its client-tier LIVE_DEGRADED status-bar state (architecturally distinct from server-side VERDICT_DEGRADED_STALE per dispatch §2.3 ratification + verdict-envelope.v1 schema doc-comment). The envelope schema's status enum is [ALLOW, WARN, DENY] only — UNREACHABLE has no envelope; it is by definition the absence-of-envelope path.",
|
|
3
|
-
"_kind": "transport_error_synthetic",
|
|
4
|
-
"_envelope": null,
|
|
5
|
-
"transport_error": {
|
|
6
|
-
"kind": "transient",
|
|
7
|
-
"message": "connection refused / DNS NXDOMAIN / 5xx after retry budget exhausted",
|
|
8
|
-
"endpoint": "https://cleanlib-enrich.clnstrt.dev"
|
|
9
|
-
},
|
|
10
|
-
"_expected_client_state": {
|
|
11
|
-
"cli_exit_code": 3,
|
|
12
|
-
"cli_status_label": "UNREACHABLE",
|
|
13
|
-
"extension_status_bar": "LIVE_DEGRADED",
|
|
14
|
-
"reason_code_when_envelope_assembled_from_cache_hit": "CLIENT_NETWORK_UNREACHABLE"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract: rich_data.abandonment_score >= 0.7 → status=WARN, reason_code=VERDICT_ABANDONED. Score field MUST drive the derivation; reason text is descriptive only.",
|
|
3
|
-
"status": "WARN",
|
|
4
|
-
"reason_code": "VERDICT_ABANDONED",
|
|
5
|
-
"human_message": "stale-lib-fixture 0.9.0 — abandoned (no commits since 2022; 0 active maintainers).",
|
|
6
|
-
"as_of": "2026-05-28",
|
|
7
|
-
"rich_data": {
|
|
8
|
-
"abandonment_score": 0.85,
|
|
9
|
-
"repo_health": {
|
|
10
|
-
"last_commit_at": "2022-01-15T00:00:00Z",
|
|
11
|
-
"maintainer_count": 0
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-warn-has-remediation.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_doc": "DeriveStatus contract: remediation.fix OR remediation.recommended_version present (under remediation block, not rich_data) → status=WARN, reason_code=VERDICT_HAS_REMEDIATION. Distinction vs verdict-allow-recommended: this fixture's recommended_version sits under remediation (signals active vuln with fix path); the allow-recommended fixture has rich_data.recommended_version (benign upgrade hint, no active vuln). Per dispatch §3.2 block tie-break: fix > recommended_version > other blocks.",
|
|
3
|
-
"status": "WARN",
|
|
4
|
-
"reason_code": "VERDICT_HAS_REMEDIATION",
|
|
5
|
-
"human_message": "vuln-with-fix-fixture 1.0.0 — vulnerable; upgrade available.",
|
|
6
|
-
"as_of": "2026-05-28",
|
|
7
|
-
"remediation": {
|
|
8
|
-
"fix": {
|
|
9
|
-
"availability": "available",
|
|
10
|
-
"as_of": "2026-05-20"
|
|
11
|
-
},
|
|
12
|
-
"recommended_version": {
|
|
13
|
-
"availability": "available",
|
|
14
|
-
"as_of": "2026-05-20"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|