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.
Files changed (38) hide show
  1. cleanlib_sdk-0.4.4/CHANGELOG.md +41 -0
  2. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/PKG-INFO +12 -17
  3. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/README.md +7 -12
  4. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/__init__.py +1 -1
  5. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/pyproject.toml +20 -5
  6. cleanlib_sdk-0.4.2/bitbucket-pipelines.yml +0 -55
  7. cleanlib_sdk-0.4.2/tests/__init__.py +0 -0
  8. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/CORPUS-README.md +0 -96
  9. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/EXPECTED.json +0 -50
  10. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-allow-clean.json +0 -7
  11. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-allow-recommended.json +0 -17
  12. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-degraded-stale.json +0 -18
  13. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-deny-exploitation-critical.json +0 -21
  14. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-deny-kev.json +0 -21
  15. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-unreachable.json +0 -16
  16. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-warn-abandoned.json +0 -14
  17. cleanlib_sdk-0.4.2/tests/fixtures/contract-fixtures/fixtures/verdict-warn-has-remediation.json +0 -17
  18. cleanlib_sdk-0.4.2/tests/test_attestation.py +0 -117
  19. cleanlib_sdk-0.4.2/tests/test_client_construct.py +0 -46
  20. cleanlib_sdk-0.4.2/tests/test_error_mapping.py +0 -90
  21. cleanlib_sdk-0.4.2/tests/test_v041_contract_and_clients.py +0 -221
  22. cleanlib_sdk-0.4.2/tests/test_v042_enrich_cascade.py +0 -603
  23. cleanlib_sdk-0.4.2/tests/test_v04_rich_data_and_verbs.py +0 -205
  24. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/.gitignore +0 -0
  25. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/client.py +0 -0
  26. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/derive_status.py +0 -0
  27. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/errors.py +0 -0
  28. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/__init__.py +0 -0
  29. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/enrich_client.py +0 -0
  30. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/enrich_types.py +0 -0
  31. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/remediation_client.py +0 -0
  32. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/types.py +0 -0
  33. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/http/verdict_client.py +0 -0
  34. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/reason_codes.py +0 -0
  35. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/schema/__init__.py +0 -0
  36. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/schema/verdict_envelope_v1.py +0 -0
  37. {cleanlib_sdk-0.4.2 → cleanlib_sdk-0.4.4}/cleanlib_sdk/transport.py +0 -0
  38. {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.2
4
- Summary: CleanLibrary Python SDK — HttpVerdictClient + HttpRemediationClient + HttpEnrichClient triad (sister-shape with @cleanstart/cleanlib-sdk v0.4.2)
5
- Project-URL: Homepage, https://bitbucket.org/triamsec/cleanlib-sdk-py
6
- Project-URL: Source, https://bitbucket.org/triamsec/cleanlib-sdk-py
7
- Project-URL: Documentation, https://bitbucket.org/triamsec/cleanlib/src/main/workstream-specs/05-app/sdk-substrate-rev1.md
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-py
26
+ # cleanlib-sdk
27
27
 
28
28
  CleanLibrary Python SDK — `asyncio` + `httpx`; mirrors the Rust `cleanlib-client` HTTP surface.
29
29
 
30
- **Status**: `v0.1.0-substrate` (cycle-4 §D.1). Substrate-only `fetch_verdict` ships; remaining verbs (`scan` / `audit_recent` / `policy_preview` / `fetch_bytes`) iterate cycle-5+.
30
+ **Status**: `v0.4.3` — production-ready.
31
31
 
32
- ## Install (cycle-5+; not yet on PyPI)
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
- - [App workstream substrate spec](https://bitbucket.org/triamsec/cleanlib/src/main/workstream-specs/05-app/sdk-substrate-rev1.md) — canonical surface design
97
- - [Rust cleanlib-client](https://bitbucket.org/triamsec/cleanlib/src/main/cleanlib-client/) — reference implementation
98
- - [App customer endpoint contract](https://bitbucket.org/triamsec/cleanlib/src/main/workstream-specs/05-app/app-scope-outline-rev4.md) §9 — HTTP surface contract
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-py
1
+ # cleanlib-sdk
2
2
 
3
3
  CleanLibrary Python SDK — `asyncio` + `httpx`; mirrors the Rust `cleanlib-client` HTTP surface.
4
4
 
5
- **Status**: `v0.1.0-substrate` (cycle-4 §D.1). Substrate-only `fetch_verdict` ships; remaining verbs (`scan` / `audit_recent` / `policy_preview` / `fetch_bytes`) iterate cycle-5+.
5
+ **Status**: `v0.4.3` — production-ready.
6
6
 
7
- ## Install (cycle-5+; not yet on PyPI)
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
- - [App workstream substrate spec](https://bitbucket.org/triamsec/cleanlib/src/main/workstream-specs/05-app/sdk-substrate-rev1.md) — canonical surface design
72
- - [Rust cleanlib-client](https://bitbucket.org/triamsec/cleanlib/src/main/cleanlib-client/) — reference implementation
73
- - [App customer endpoint contract](https://bitbucket.org/triamsec/cleanlib/src/main/workstream-specs/05-app/app-scope-outline-rev4.md) §9 — HTTP surface contract
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
 
@@ -99,7 +99,7 @@ from cleanlib_sdk.types import (
99
99
  Verdict,
100
100
  )
101
101
 
102
- __version__ = "0.4.2"
102
+ __version__ = "0.4.4"
103
103
 
104
104
  __all__ = [
105
105
  # v0.4.2 per-domain HTTP client triad (primary API)
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cleanlib-sdk"
7
- version = "0.4.2"
8
- description = "CleanLibrary Python SDK — HttpVerdictClient + HttpRemediationClient + HttpEnrichClient triad (sister-shape with @cleanstart/cleanlib-sdk v0.4.2)"
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://bitbucket.org/triamsec/cleanlib-sdk-py"
36
- Source = "https://bitbucket.org/triamsec/cleanlib-sdk-py"
37
- Documentation = "https://bitbucket.org/triamsec/cleanlib/src/main/workstream-specs/05-app/sdk-substrate-rev1.md"
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
- }
@@ -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
- }
@@ -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
- }